Remove AI tooling and working docs from repo tracking
Add .agent/, .mcp.json, CLAUDE.md, AGENTS.md, GEMINI.md, QUICKSTART.md, bootstrap.sh, docs/memory/, and docs/reference/ (impeccable, vercel, workflow guides) to .gitignore. Files remain on disk for local use but are no longer tracked or pushed to remotes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,118 +0,0 @@
|
||||
# Component registry
|
||||
|
||||
Tracks the status, specification, and key details of every component in the
|
||||
design system. Agents MUST check this before building a component (to avoid
|
||||
duplicates) and MUST update it after completing one.
|
||||
|
||||
## Status definitions
|
||||
|
||||
- **planned**: Component is identified but not yet started
|
||||
- **in-progress**: Component is being built
|
||||
- **review**: Component is built, awaiting human review
|
||||
- **done**: Component is reviewed and approved
|
||||
- **needs-revision**: Component needs changes based on review feedback
|
||||
|
||||
## Atoms
|
||||
|
||||
| Component | Status | Variants | Tokens used | Notes |
|
||||
|-----------|--------|----------|-------------|-------|
|
||||
| Button | done | contained, soft, outlined, text × xs, small, medium, large × primary, secondary + loading, underline, fullWidth | button.height/paddingX/paddingY/fontSize/iconSize/iconGap/borderRadius, color.interactive.*, color.brand.100-300, color.neutral.200-700 | Primary interactive element. Merges Text Button from Figma. Soft variant = Figma's Secondary/Brand & Secondary/Grey. |
|
||||
| IconButton | done | default, primary, secondary, error × small, medium, large | Reuses button.height/iconSize tokens, color.interactive.*, color.neutral.* | Icon-only button (close, menu, actions). Wraps MUI IconButton. Rounded rect, brand hover, focus ring. |
|
||||
| Typography | done | displayHero, display1-3, displaySm, h1-h6, bodyLg, body1, body2, bodyXs, labelLg, label, labelSm, caption, captionSm, overline, overlineSm + maxLines, gutterBottom | typography.* (all semantic typography tokens), fontFamily.body, fontFamily.display | Text display system. Thin MUI wrapper with maxLines truncation. |
|
||||
| Input | done | medium, small × default, hover, focus, error, success, disabled + startIcon, endIcon, required, multiline | input.height/paddingX/paddingY/fontSize/borderRadius/gap/iconSize, color.neutral.300-400, color.brand.500, color.feedback.error/success, color.text.secondary | External label pattern, branded focus ring, two sizes aligned with Button. Adds startIcon/endIcon and success state beyond Figma. |
|
||||
| Badge | done | soft, filled × default, brand, success, warning, error, info × small, medium + icon | badge.height/paddingX/fontSize/iconSize/iconGap/borderRadius, color.feedback.*, color.brand.200/700 | Status indicator pill. Soft (tonal) or filled (solid). 6 colours, 2 sizes, optional leading icon. |
|
||||
| Icon | planned | various sizes | | Icon wrapper component |
|
||||
| Avatar | planned | image, initials, icon × small, medium, large | | User/entity representation |
|
||||
| Divider | done | horizontal, vertical × fullWidth, inset, middle + text, flexItem | color.border.default (via palette.divider) | Visual separator. Wraps MUI Divider. Supports text children and orientation. |
|
||||
| Chip | done | filled, outlined × small, medium × clickable, deletable, selected × default, primary | chip.height/paddingX/fontSize/iconSize/deleteIconSize/iconGap/borderRadius, color.neutral.200-700, color.brand.200-700 | Interactive tag. Wraps MUI Chip with FA tokens. Selected state promotes to brand colour. Filled uses soft tonal bg (like Badge). |
|
||||
| Card | done | elevated, outlined × default, compact, none padding × interactive × selected | card.borderRadius/padding/shadow/border/background, color.surface.raised/subtle/warm, color.border.default/brand, shadow.md/lg | Content container. Elevated (shadow) or outlined (border). Interactive adds hover bg fill + shadow lift. Selected adds brand border + warm bg. Three padding presets. |
|
||||
| Switch | done | bordered style × checked, unchecked, disabled | switch.track.width/height/borderRadius, switch.thumb.size, color.interactive.*, color.neutral.400 | Toggle for add-ons/options. Wraps MUI Switch. Bordered pill, brand.500 fill when active. From Parsons 1.0 Figma Style One. |
|
||||
| Radio | done | checked, unchecked, disabled | radio.size/dotSize, color.interactive.*, color.neutral.400 | Single-select option. Wraps MUI Radio. Brand.500 fill when selected. From Parsons 1.0 Figma. |
|
||||
| MapPin | done | name+price (two-line), name-only, price-only × verified, unverified × default, active | mapPin.paddingX/borderRadius/nub.size, color.brand.100-900, color.neutral.100-800 | Two-line label map marker: name (bold, truncated 180px) + "From $X" (centred, semibold). Name optional for price-only variant. Verified = brand palette, unverified = grey. Active inverts + scale. Pure CSS. role="button" + keyboard + focus ring. |
|
||||
| ColourToggle | planned | inactive, hover, active, locked × single, two-colour × desktop, mobile | | Circular colour swatch picker for products. Custom component. Deferred until product detail organisms. |
|
||||
| Slider | planned | single, range × desktop, mobile | | Price range filter. Wraps MUI Slider. Deferred until search/filtering molecules. |
|
||||
| Link | done | underline: hover/always/none × any MUI colour | color.text.brand (copper brand.600, 4.8:1), color.interactive.active | Navigation text link. Wraps MUI Link. Copper default, underline on hover, focus ring. |
|
||||
| Collapse | done | in/out × unmountOnExit | (none — uses MUI defaults) | Progressive disclosure wrapper. Thin MUI Collapse wrapper with unmountOnExit default. Slide-down animation for wizard field reveal. |
|
||||
| DialogShell | done | open/closed × with/without back button × with/without footer | (theme defaults — borderRadius, palette) | Standard dialog container. Header (title + optional back + close), divider, scrollable body, optional footer. Used by FilterPanel and ArrangementDialog. |
|
||||
| ToggleButtonGroup | done | exclusive single-select × small, medium, large × error × fullWidth + descriptions | color.neutral.100-200, color.brand.50/100, color.interactive.focus, color.feedback.error | Button-select for binary/small-set choices. Fieldset/legend a11y, external label, helper/error text. Brand styling on selected. |
|
||||
|
||||
## Molecules
|
||||
|
||||
| Component | Status | Composed of | Notes |
|
||||
|-----------|--------|-------------|-------|
|
||||
| MiniCard | done | Card + Typography + Badge + Tooltip | Compact vertical card for grids, recommendations, map popups. Image + title + optional price/badges/chips/meta (location, rating, capacity). Verified = icon-only circle badge in image. Hierarchy: title → meta → price → badges → chips. Truncated title shows tooltip. 3 component tokens. Audit: 20/20. |
|
||||
| MapPopup | done | Paper + Typography + Tooltip | Floating map popup anchored to MapPin. Clickable card (onClick). Image + name (1 line, tooltip) + meta + price. Verified = icon-only circle badge in image (matches MiniCard). Hierarchy matches MiniCard. Nub + drop-shadow. 260px wide. |
|
||||
| FormField | planned | Input + Typography (label) + Typography (helper) | Standard form field with label and validation |
|
||||
| ProviderCard | done | Card + Typography + Badge + Tooltip | Provider listing card. Verified: image + logo (64px rounded rect) + "Verified" badge. Unverified: text-only with top accent bar. Capability badges with info icon + tooltip. Price split typography. No footer. 4 component tokens. |
|
||||
| VenueCard | done | Card + Typography | Venue listing card. Always has photo + location + capacity ("X guests") + price ("From $X"). No verification tiers, no logo, no badges. 3 component tokens. Critique: 33/40. |
|
||||
| MapCard | planned | Card + Typography + Badge | Compact horizontal map popup card. Deferred until map integration. |
|
||||
| ServiceOption | done | Card (interactive, selected) + Typography | Selectable service option for arrangement flow. Heading + optional price (right-aligned) + optional description. role="radio" + aria-checked. Disabled state with opacity token. Maps to Figma ListItemPurchaseOption. |
|
||||
| SearchBar | done | Input + IconButton + Button | Search input with optional submit button. Enter-to-submit, progressive clear button, inline loading spinner. Guards empty submissions, refocuses after clear. role="search" landmark. Critique: 35/40. |
|
||||
| AddOnOption | done | Card (interactive, selected) + Typography + Switch | Toggleable add-on for arrangement flow extras. Heading + optional price + description + Switch. Click-anywhere toggle. Maps to Figma ListItemAddItem (2350:40658). |
|
||||
| StepIndicator | done | Typography + Box | Horizontal segmented progress bar. Brand gold for completed/current steps, grey for upcoming. Responsive bar height (10px/6px). Maps to Figma Progress Bar - Steps (2375:47468). |
|
||||
| LineItem | done | Typography + Tooltip + InfoOutlinedIcon | Name + optional info tooltip + optional price. Supports allowance asterisk, total variant (bold + top border). Font weight 500 (D019), prices text.secondary for readability hierarchy. Audit: 19/20. |
|
||||
| ProviderCardCompact | done | Card (outlined) + Typography | Horizontal compact provider card — image left, name + location + rating right. Used at top of Package Select page. Separate from vertical ProviderCard. |
|
||||
| CartButton | done | Button + DialogShell + LineItem + Divider + Typography | Outlined pill trigger: receipt icon + "Your Plan" + formatted total in brand colour. Click opens DialogShell with items grouped by section via LineItem, total row. Mobile: icon + price only. Lives in WizardLayout `runningTotal` slot. |
|
||||
| CompareBar | done | Badge + Button + IconButton + Typography + Paper + Slide | Floating comparison basket pill. Fixed bottom, slide-up/down. Package count badge + provider names + remove buttons + Compare CTA. Max 3 user packages. Disabled CTA when <2. Inline error for max-reached. Mobile: compact count + CTA only. Audit: 18/20. |
|
||||
|
||||
## Organisms
|
||||
|
||||
| Component | Status | Composed of | Notes |
|
||||
|-----------|--------|-------------|-------|
|
||||
| ServiceSelector | done | ServiceOption × n + Typography + Button | Single-select service panel for arrangement flow. Heading + subheading + ServiceOption list (radiogroup) + optional continue Button. Manages selection state via selectedId/onSelect. maxDescriptionLines pass-through. |
|
||||
| PricingTable | planned | PriceCard × n + Typography | Comparative pricing display |
|
||||
| PackageDetail | done | LineItem × n + Typography + Button + Divider | Right-side package detail panel. Warm header band (surface.warm) with "Package" overline, name, price (brand colour), Make Arrangement + Compare (with loading) buttons. Sections: Essentials + Optionals (before total) + total + Extras (after total, with subtext). `priceLabel` pass-through to LineItem (D039). T&C grey footer. Audit: 19/20. |
|
||||
| ComparisonTable | done | Typography + Button + Badge + Link + Tooltip | Side-by-side package comparison CSS Grid. Sticky header cards with provider info + price + CTA. Row-merged sections (union of all items). 7 cell value types (discriminated union D036). Recommended column with warm bg + badge. Verified → "Make Arrangement", unverified → "Make Enquiry". ARIA table roles. Desktop only (mobile in ComparisonPage). Audit: 17/20. |
|
||||
| FuneralFinder (V3) | done | Typography + Button + Divider + Select + MenuItem + OutlinedInput + custom StatusCard/SectionLabel | **Production version.** Hero search widget — clean form with status cards. Standard card container (surface.raised, card shadow). "How Can We Help" section: two side-by-side StatusCards (Immediate Need default-selected / Pre-planning) — white bg, neutral border, brand border + warm bg when selected, stack on mobile. "Funeral Type" Select + "Location" OutlinedInput with pin icon — standard outlined fields, no focus ring (per design). Overline section labels (text.secondary). CTA "Find Funeral Directors →" always active — validates on click, scrolls to first missing field. Required: status + location. Funeral type defaults to "show all". Dividers after header and before CTA. WAI-ARIA roving tabindex on radiogroup. aria-labelledby via useId(). Critique: 33/40 (Good). Audit: 18/20 (Excellent). |
|
||||
| FuneralFinder V1 | archived | Typography + Button + Chip + Input + Divider + Link + custom ChoiceCard/TypeCard/CompletedRow/StepHeading | Archived — viewable in Storybook under Archive/. Stepped conversational flow. Audit: 14/20. Critique: 29/40. |
|
||||
| FuneralFinder V2 | archived | Typography + Button + Input + Divider + Select + MenuItem + custom StepCircle | Archived — viewable in Storybook under Archive/. Quick-form with step circles. Audit: 18/20. Critique: 33/40. |
|
||||
| FuneralFinder V4 | archived | Typography + Button + Input + Divider + Select + MenuItem + custom StepIndicator/FieldError | Archived. Based on V2 with: 3 numbered steps (48px circles, outline-to-fill + tick), ungated location field, no heading/subheading, "Search" CTA, inline copper error messages. |
|
||||
| ArrangementForm | planned | StepIndicator + ServiceSelector + AddOnOption + Button + Typography | Multi-step arrangement wizard. Deferred — build remaining atoms/molecules first. |
|
||||
| Navigation | done | AppBar + Link + IconButton + Button + Divider + Drawer | Responsive site header. Desktop: logo left, links right, optional CTA. Mobile: hamburger + drawer with nav items, CTA, help footer. Sticky, grey surface bg (surface.subtle). Real FA logo from brandassets/. Maps to Figma Main Nav (14:108) + Mobile Header (2391:41508). |
|
||||
| Footer | done | Link × n + Typography + Divider + Container + Grid | Light grey (surface.subtle) site footer — matches header. Logo + tagline + contact (phone/email) + link group columns + legal bar. Semantic HTML (footer, nav, ul). Critique: 38/40 (Excellent). |
|
||||
|
||||
## Templates
|
||||
|
||||
| Component | Status | Composed of | Notes |
|
||||
|-----------|--------|-------------|-------|
|
||||
| WizardLayout | done | Container + Box + Link + Typography + Navigation (slot) + StepIndicator (slot) | Page-level layout for arrangement wizard. 5 variants: centered-form, list-map, list-detail, grid-sidebar, detail-toggles. Nav slot, sticky help bar, optional back link, optional progress stepper + running total. `<main>` landmark wrapper. |
|
||||
|
||||
## Pages
|
||||
|
||||
| Component | Status | Composed of | Notes |
|
||||
|-----------|--------|-------------|-------|
|
||||
| IntroStep | done | WizardLayout (centered-form) + ToggleButtonGroup × 2 + Collapse + Typography + Button + Divider | Wizard step 1 — entry point. forWhom (Myself/Someone else) + hasPassedAway (Yes/No) with progressive disclosure. Auto-sets hasPassedAway="no" for "Myself". `<form>` wrapper, aria-live subheading, grief-sensitive copy. Pure presentation. Audit: 18/20 → 20/20 after fixes. |
|
||||
| ProvidersStep | done | WizardLayout (list-map) + ProviderCard + SearchBar + Chip + Typography + Button | Wizard step 2 — provider selection. List-map split: provider cards w/ radiogroup + search + filter chips (left), map slot (right). aria-live results count, back link. ProviderCard extended with HTML/ARIA passthrough. Audit: 18/20. |
|
||||
| PackagesStep | done | WizardLayout (list-detail) + ProviderCardCompact + ServiceOption + PackageDetail + Badge + TextField + Typography + Button | Wizard step 3 — package selection. List-detail split: compact provider + budget filter + package list w/ radiogroup (left), PackageDetail breakdown (right). "Most Popular" badge. Mobile Continue button. |
|
||||
| ~~PreviewStep~~ | removed | — | Replaced by ArrangementDialog organism (D-E). Package preview + "what's next" checklist now in the dialog's preview step. |
|
||||
| ~~AuthGateStep~~ | removed | — | Replaced by ArrangementDialog organism (D-E). SSO/email auth flow now in the dialog's auth step. |
|
||||
| DateTimeStep | done | WizardLayout (centered-form) + Input + TextField (date) + RadioGroup + Collapse + Divider + Button + Link | Wizard step 6 — details & scheduling. Deceased name (Input atom, external label) + preferred dates (up to 3, progressive disclosure) + time-of-day radios. Service tradition removed (flows from provider/package). Dividers between sections. Grief-sensitive labels. Save-and-exit CTA. |
|
||||
| VenueStep | done | WizardLayout (centered-form) + VenueCard + AddOnOption + Collapse + Chip + TextField + Divider + Button | Wizard step 7a — venue browsing. Click-to-navigate card grid with search/filters. Leads to VenueDetailStep. |
|
||||
| VenueDetailStep | done | WizardLayout (detail-toggles) + ImageGallery + Card + Chip + Typography + Button + Divider | Wizard step 7b — venue detail. Two-panel: gallery/description/features/location (left), name/meta/price/CTA/religions (right). Informational service preview. |
|
||||
| VenueServicesStep | done | WizardLayout (centered-form) + AddOnOption + Card + Typography + Button + Divider | Wizard step 7c — venue services. Compact venue card, availability notices, AddOnOption toggles with "View more" for long descriptions. Follows VenueDetailStep. |
|
||||
| CrematoriumStep | done | WizardLayout (centered-form) + Card + Badge + ToggleButtonGroup + Typography + Button + Divider | Wizard step 8 — crematorium. Two variants: Service & Cremation (compact card + witness Yes/No toggle), Cremation Only (compact card + "Cremation Only" badge + "Included in Package" notice). Single pre-selected crematorium, no multi-select. |
|
||||
| CemeteryStep | done | WizardLayout (centered-form) + ToggleButtonGroup + Collapse + TextField (select) + Typography + Button + Divider | Wizard step 9 — cemetery. ToggleButtonGroups (Yes/No/Not sure) with progressive disclosure. Own plot → locate dropdown. No plot → preference? → select dropdown. No card grid. |
|
||||
| CoffinsStep | done | WizardLayout (grid-sidebar) + Card + Badge + Collapse + Slider + TextField + Pagination + Divider + Link | Wizard step 10 — coffin browsing. Grid-sidebar: filter sidebar (categories with expandable subcategories, dual-knob price slider with editable inputs, sort by) + 3-col card grid. CoffinCard with thumbnail hover preview. Equal-height cards, subtle bg for white-bg product photos. Card click → CoffinDetailsStep (no Continue). 20/page max. Conditional allowance info bubble. |
|
||||
| CoffinDetailsStep | done | WizardLayout (detail-toggles) + ImageGallery + Divider + Button | Wizard step 11 — coffin detail. Two-panel: gallery + product details dl (left), name + description + colour swatches + allowance-aware price + CTA (right). Allowance logic: fully covered / partially covered / no allowance. Colour selection does not affect price. |
|
||||
| ~~AdditionalServicesStep~~ | removed | — | Replaced by IncludedServicesStep + ExtrasStep. Split for clearer distinction between free inclusions and paid extras. |
|
||||
| IncludedServicesStep | done | WizardLayout (centered-form) + AddOnOption + RadioGroup + Collapse + Divider + Button | Wizard step 12a — included services. Package inclusions at no additional cost: dressing, viewing (with same-venue sub-option), prayers/vigil, funeral announcement. Sub-options render inside parent card. |
|
||||
| ExtrasStep | done | WizardLayout (centered-form) + AddOnOption + Card + Switch + RadioGroup + Collapse + Divider + Button | Wizard step 12b — optional extras. Lead-gen interest capture: catering, music (inline live musician toggle + musician type), coffin bearing (toggle + bearer type), newspaper notice. POA via `priceLabel`. Tally of priced selections. No nested cards. |
|
||||
| SummaryStep | done | WizardLayout (centered-form) + Card + Paper + DialogShell + Button + Link + Divider | Wizard step 13 — plan review. Visual cart layout: arrangement details (2-col grid), compact cards with thumbnails for provider/venue/crematorium/coffin, checklist for included services, priced list for extras. Allowance display (fully covered vs remaining). Share dialog (multi-email). Location pin icons. Full-width CTA. |
|
||||
| PaymentStep | done | WizardLayout (centered-form) + ToggleButtonGroup + Paper + Collapse + Checkbox + Divider + Button | Wizard step 14 — payment. Plan (full/deposit) + method (card/bank). PayWay iframe slot. Bank transfer details. Terms checkbox. |
|
||||
| ConfirmationStep | done | WizardLayout (centered-form) + Button | Wizard step 15 — confirmation. Terminal page. At-need: "submitted" + callback. Pre-planning: "saved" + return-anytime. Muted success icon. |
|
||||
| UnverifiedProviderStep | done | WizardLayout (list-detail) + ProviderCardCompact + ProviderCard + Badge + Button + Divider + Typography | Unverified provider detail. Left: compact card + "Listing" badge + available info (conditional dl) + verified recommendations. Right: warm header band + detail rows + "Make an Enquiry" CTA. Graceful degradation (no data → straight to enquiry). 4 story variants. |
|
||||
| HomePage | done | FuneralFinderV3/V4 (via finderSlot) + ProviderCardCompact + Button + Typography + Accordion + Divider + Navigation (prop) + Footer (prop) | Marketing landing page. 4 archived versions: V1 (split hero), V2 (full-bleed parsonshero.png), V3 (hero-3.png + updated copy + logo bar + venue photos + warm CTA gradient), V4 (same as V3 but with FuneralFinderV4 stepped form via finderSlot). `finderSlot` prop allows swapping finder widget. Light grey footer (surface.subtle). |
|
||||
| ComparisonPage | done | WizardLayout (wide-form) + ComparisonTable + Chip + Card + LineItem + Typography + Button + Divider | Package comparison page. Desktop: full ComparisonTable with sticky headers. Mobile: tabbed card view with horizontal chip rail (role="tablist") + single package card (role="tabpanel"). Recommended package as additional column/tab (separate prop D038). Back link, help bar. |
|
||||
|
||||
## Future enhancements
|
||||
|
||||
Deferred items that should be addressed when the relevant components or patterns
|
||||
are needed. Check this section before building new components — an item here may
|
||||
be relevant to your current work.
|
||||
|
||||
| Item | Relates to | Trigger | Notes |
|
||||
|------|-----------|---------|-------|
|
||||
| Destructive button colours | Button | When building delete/cancel flows | `color="error"` already works via MUI palette. May need `soft` variant styling for error/warning/success colours. |
|
||||
| Link-as-button | Button | When building Navigation or link-heavy pages | Use MUI's `component="a"` or `href` prop. May warrant a separate Link atom or a `Button` story showing the pattern. |
|
||||
| ~~IconButton atom~~ | ~~IconButton~~ | ~~Resolved~~ | ~~Built as atom. Rounded rect, 3 sizes, 4 colours, focus ring.~~ |
|
||||
| ~~Google Fonts loading~~ | ~~Typography~~ | ~~Resolved~~ | ~~Added to .storybook/preview-head.html and index.html~~ |
|
||||
@@ -1,335 +0,0 @@
|
||||
# Design decisions log
|
||||
|
||||
Every design decision that affects tokens, components, or system architecture
|
||||
MUST be logged here with rationale. This ensures consistency across sessions
|
||||
and agents. Agents MUST check this file before making any decision that could
|
||||
contradict a previous one.
|
||||
|
||||
## Format
|
||||
|
||||
```
|
||||
### [Decision ID] — [Short title]
|
||||
**Date:** [date]
|
||||
**Category:** token | component | architecture | convention
|
||||
**Decision:** [What was decided]
|
||||
**Rationale:** [Why this decision was made]
|
||||
**Affects:** [Which tokens/components/files this impacts]
|
||||
**Alternatives considered:** [What else was considered and why it was rejected]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Decisions
|
||||
|
||||
### D001 — Primary brand colour is warm gold #BA834E
|
||||
**Date:** 2025-03-25
|
||||
**Category:** token
|
||||
**Decision:** Primary brand colour (color.brand.500) is #BA834E — warm gold.
|
||||
**Rationale:** Extracted from Parsons brand swatches. Matches the existing FA 1.0 CTA button colour ("Add to package"). Warm gold conveys trust and professionalism appropriate for funeral services. The colour has a 3.7:1 contrast ratio on white, suitable for large text and interactive elements (buttons with white text).
|
||||
**Affects:** color.brand.500, color.interactive.default, MUI palette.primary.main
|
||||
**Alternatives considered:** #B0610F (copper) was considered for primary but it's darker and more aggressive. Placed at brand.600 for hover/emphasis instead.
|
||||
|
||||
### D002 — Primary text colour is charcoal #2C2E35 (not pure black)
|
||||
**Date:** 2025-03-25
|
||||
**Category:** token
|
||||
**Decision:** Primary text colour is #2C2E35 (color.neutral.800) — charcoal with cool blue undertone.
|
||||
**Rationale:** From brand swatch. Softer than pure black for extended reading comfort while maintaining 13.2:1 contrast ratio on white (well exceeds WCAG AA). The cool undertone complements the sage secondary palette.
|
||||
**Affects:** color.text.primary, MUI palette.text.primary
|
||||
**Alternatives considered:** Pure black (#000000) — higher contrast but causes eye fatigue on white backgrounds. Added as color.black for rare use.
|
||||
|
||||
### D003 — Brand link/accent colour uses copper #B0610F
|
||||
**Date:** 2025-03-25
|
||||
**Category:** token
|
||||
**Decision:** Brand-coloured text (links, inline emphasis) uses #B0610F (color.brand.600 / copper) not the base gold.
|
||||
**Rationale:** The base gold #BA834E has only 3.7:1 contrast on white which doesn't meet WCAG AA for normal text (4.5:1 required). The copper #B0610F provides 4.8:1 contrast, meeting AA. It's also visually more assertive for link text.
|
||||
**Affects:** color.text.brand, color.interactive.hover
|
||||
**Alternatives considered:** brand.700 (#8B4E0D) at 6.7:1 — meets AAA but is too dark and loses the warm "brand" feel.
|
||||
|
||||
### D004 — Sage palette as secondary colour family
|
||||
**Date:** 2025-03-25
|
||||
**Category:** token
|
||||
**Decision:** Secondary palette uses cool sage/slate tones (#4C5B6B as sage.700) rather than a second warm colour.
|
||||
**Rationale:** From brand swatches (cool row). The sage provides visual contrast against the warm brand palette and adds a calming, professional quality appropriate for the funeral services context. Used for secondary buttons and less prominent actions.
|
||||
**Affects:** color.sage.*, color.interactive.secondary, MUI palette.secondary
|
||||
**Alternatives considered:** Using a lighter warm tone for secondary — rejected as it wouldn't provide enough visual distinction from primary.
|
||||
|
||||
### D005 — Display font is Noto Serif SC for H1-H2 headings
|
||||
**Date:** 2025-03-25
|
||||
**Category:** token
|
||||
**Decision:** Display/heading font is Noto Serif SC for Display, H1, and H2 levels. H3+ use Montserrat (body font).
|
||||
**Rationale:** User specified Noto Serif SC as display font and Montserrat as primary. The serif at H1-H2 adds warmth and gravitas suitable for funeral services. H3+ switches to Montserrat to create a clear hierarchy break.
|
||||
**Affects:** fontFamily.display, fontFamily.body, typography.display/h1/h2/h3/h4
|
||||
**Alternatives considered:** Using serif for all headings — rejected as it would make H3/H4 feel too formal at smaller sizes.
|
||||
|
||||
### D006 — Warning text uses amber.700 for AA compliance
|
||||
**Date:** 2025-03-25
|
||||
**Category:** token
|
||||
**Decision:** Warning text colour is amber.700 (#A36B00) not amber.600 (#CC8500).
|
||||
**Rationale:** amber.600 (3.6:1 contrast on white) only passes AA for large text. For warning text that must be readable at body size, amber.700 at 5.1:1 meets WCAG AA for normal text.
|
||||
**Affects:** color.text.warning
|
||||
**Alternatives considered:** amber.800 — passes AAA but is too dark to read as "amber/warning".
|
||||
|
||||
### D007 — Style Dictionary requires usesDtcg: true
|
||||
**Date:** 2025-03-25
|
||||
**Category:** architecture
|
||||
**Decision:** Added `usesDtcg: true` to Style Dictionary v4.4.0 config.
|
||||
**Rationale:** Without this flag, SD v4 doesn't properly populate `allTokens` for the CSS `css/variables` format, resulting in empty CSS output. JS and JSON formats work without it but CSS requires it for DTCG token format.
|
||||
**Affects:** style-dictionary/config.js, CSS output
|
||||
**Alternatives considered:** Custom format — rejected as the built-in format works correctly with the flag.
|
||||
|
||||
### D008 — Responsive typography via @media in MUI theme
|
||||
**Date:** 2025-03-25
|
||||
**Category:** architecture
|
||||
**Decision:** Mobile font sizes are handled via `@media (max-width:600px)` queries in the MUI theme typography config, not via `responsiveFontSizes()`.
|
||||
**Rationale:** Explicit media queries allow precise control over mobile sizes (28px, 24px, 20px, 18px) matching the token definitions. MUI's `responsiveFontSizes()` uses its own scaling algorithm that can't be configured to match our exact values.
|
||||
**Affects:** src/theme/index.ts, typography.*.fontSizeMobile tokens
|
||||
**Alternatives considered:** `responsiveFontSizes()` utility — rejected due to lack of precise size control.
|
||||
|
||||
### D009 — Merge Text Button into Button atom
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Text Button is not a separate atom. It is implemented as `<Button variant="text">` with an optional `underline` prop for link-style appearance.
|
||||
**Rationale:** In MUI, text buttons are a variant of Button (`variant="text"`), not a separate component. Having both Button and TextButton creates API confusion. The Figma "ghost" variant and "text button" both map to MUI's text variant. The `underline` prop handles the design's "default.underline" state.
|
||||
**Affects:** Button component API, Storybook story structure
|
||||
**Alternatives considered:** Separate TextButton component — rejected as it duplicates Button logic and creates ambiguity for developers.
|
||||
|
||||
### D010 — Button sizes adjusted for touch targets
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Button sizes are xs: 28px, sm: 32px, md: 40px, lg: 48px — all multiples of 4px. Large size (48px) meets the 44px minimum touch target for mobile.
|
||||
**Rationale:** Original Figma sizes (sm: 26px, md: 37px) don't meet the 44px minimum touch target specified in the design system conventions. Adjusted to a clean 4px-grid scale that includes a large size suitable for mobile CTAs. FA's audience may be older or in emotional distress — generous touch targets are important.
|
||||
**Affects:** tokens/component/button.json, MUI theme MuiButton overrides
|
||||
**Alternatives considered:** Keeping original Figma sizes — rejected because neither met the 44px touch target minimum.
|
||||
|
||||
### D011 — Use @mui/icons-material over Font Awesome
|
||||
**Date:** 2026-03-25
|
||||
**Category:** architecture
|
||||
**Decision:** Primary icon source is `@mui/icons-material`. Custom SVGs wrapped in MUI's `SvgIcon` for any FA-specific icons.
|
||||
**Rationale:** MUI icons extend `SvgIcon`, so they work natively with MUI Button's `startIcon`/`endIcon`, inherit theme colours, and are tree-shakeable. Font Awesome requires an adapter layer to work with MUI's icon API. All standard UI icons from the Figma designs exist in the MUI icon set.
|
||||
**Affects:** Icon approach, Button icon integration, dependencies
|
||||
**Alternatives considered:** `@fortawesome/react-fontawesome` — rejected due to adapter complexity and extra dependency. User was using FA icons in Figma but agreed MUI icons are more pragmatic for the code implementation.
|
||||
|
||||
### D012 — Button responsive sizing is a composition concern
|
||||
**Date:** 2026-03-25
|
||||
**Category:** architecture
|
||||
**Decision:** Button size is an explicit prop (`size="xs" | "small" | "medium" | "large"`), not responsive by default. Layout components choose the appropriate size per breakpoint.
|
||||
**Rationale:** Keeps the Button component simple and predictable. Responsive behaviour is a layout decision — a card might use `size="large"` on mobile for touch targets and `size="medium"` on desktop. This avoids the complexity of Figma variable modes for mobile/desktop scaling inside components.
|
||||
**Affects:** Button component API, consumer usage patterns
|
||||
**Alternatives considered:** Figma variable modes for responsive scaling within the component — rejected as over-engineered. MUI's `useMediaQuery` or responsive `sx` props handle this at the composition level.
|
||||
|
||||
### D013 — Soft variant for tonal/muted buttons
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Added `variant="soft"` custom MUI Button variant for tonal/muted fill buttons. Maps to Figma's "Secondary/Brand" and "Secondary/Grey" columns.
|
||||
**Rationale:** Figma review revealed that "Secondary/Brand" (bg #e4cdb3, text #845830) and "Secondary/Grey" (bg #dcdde0, text #434b52) are NOT outlined buttons — they are filled buttons with softer, tonal colours. This pattern is common in modern design systems (Material Design 3 calls it "tonal", Radix calls it "soft"). Primary soft uses brand.200 bg + brand.700 text. Secondary soft uses neutral.200 bg + neutral.700 text.
|
||||
**Affects:** MUI theme MuiButton variants, Button component API, Storybook stories
|
||||
**Alternatives considered:** Separate color options for each Figma column — rejected as it doesn't map to MUI's color+variant model. The soft variant is more extensible — any future color automatically gets a soft treatment.
|
||||
|
||||
### D014 — Secondary palette changed from sage to neutral grey
|
||||
**Date:** 2026-03-25
|
||||
**Category:** token
|
||||
**Decision:** MUI secondary palette changed from sage (#4C5B6B sage.700) to neutral grey (#525252 neutral.600). Sage remains available in the token system for surfaces but is no longer the secondary button colour.
|
||||
**Rationale:** User feedback that secondary buttons should match Figma's "Secondary/Grey" which uses neutral tones, not the blue-green sage. The sage palette is still valuable for cool surfaces (color.surface.cool) but shouldn't be the primary secondary interactive colour.
|
||||
**Affects:** MUI palette.secondary, all MuiButton secondary overrides (outlined, text, soft)
|
||||
**Alternatives considered:** Adding a third "neutral" custom colour and keeping sage as secondary — rejected as unnecessarily complex when no other components use the sage secondary yet.
|
||||
|
||||
### D015 — Loading spinner positioned on the right
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Button loading spinner (CircularProgress) appears after the label text, on the right side of the button.
|
||||
**Rationale:** User preference. Right-side positioning follows the convention of trailing indicators (like endIcon) and feels more natural for async state feedback.
|
||||
**Affects:** Button component render order
|
||||
**Alternatives considered:** Left-side spinner (before text) — rejected per user feedback.
|
||||
|
||||
### D016 — Primary button colour confirmed as copper (brand.600)
|
||||
**Date:** 2026-03-25
|
||||
**Category:** token
|
||||
**Decision:** Primary button fill (palette.primary.main) stays as brand.600 copper (#B0610F), not brand.500 warm gold (#BA834E). User confirmed.
|
||||
**Rationale:** Brand.600 provides 4.8:1 contrast ratio with white text, meeting WCAG AA for all text sizes. Brand.500 only achieves 3.7:1 (AA for large text only). Since button labels can vary in size, the stronger contrast is preferred. The visual warmth is preserved through the soft variant (brand.200 bg) and hover states.
|
||||
**Affects:** palette.primary.main, all contained primary buttons, interactive token
|
||||
**Alternatives considered:** Brand.500 warm gold — rejected as it doesn't meet AA for normal-sized text.
|
||||
|
||||
### D017 — Headings use Montserrat Bold, not Noto Serif SC
|
||||
**Date:** 2026-03-25
|
||||
**Category:** token
|
||||
**Decision:** All headings (h1-h6) use Montserrat Bold (700), not Noto Serif SC. Noto Serif SC is reserved exclusively for display variants (displayHero through displaySm).
|
||||
**Rationale:** User's FA 2.0 Figma design separates display (serif, for marketing/hero) from headings (sans-serif, for content structure). This is cleaner than the previous approach where h1-h2 used serif. Montserrat Bold provides strong hierarchy without the formality of serif at content-level sizes.
|
||||
**Affects:** MUI theme h1-h6 fontFamily, semantic typography tokens. Supersedes D005.
|
||||
**Alternatives considered:** Keep D005 (serif for h1-h2) — rejected per user's updated Figma design.
|
||||
|
||||
### D018 — Display weight is Regular (400), not Bold
|
||||
**Date:** 2026-03-25
|
||||
**Category:** token
|
||||
**Decision:** Display text (Noto Serif SC) uses Regular weight (400) across all 5 display levels, not Bold (700).
|
||||
**Rationale:** Serif fonts carry inherent visual weight. At 40-80px, Regular Noto Serif SC has enormous presence. Bold at these sizes would be overwhelming and less elegant.
|
||||
**Affects:** typography.displayHero/1/2/3/Sm fontWeight tokens
|
||||
**Alternatives considered:** Bold (700) — the previous implementation. Rejected per user's Figma which uses Regular.
|
||||
|
||||
### D019 — Body text weight is Medium (500)
|
||||
**Date:** 2026-03-25
|
||||
**Category:** token
|
||||
**Decision:** Body text uses Montserrat Medium (500) instead of Regular (400). User found Regular too light for comfortable reading.
|
||||
**Rationale:** User feedback that Montserrat Regular is "just a little bit too light." The Figma specified weight 450 which isn't available in Google Fonts, so 500 (Medium) is the closest available weight that provides the desired visual density.
|
||||
**Affects:** typography.body/bodyLg/bodySm/bodyXs fontWeight tokens
|
||||
**Alternatives considered:** 400 Regular — too light per user. 450 — not available in Google Fonts Montserrat.
|
||||
|
||||
### D020 — Expanded type scale: 21 variants across 6 categories
|
||||
**Date:** 2026-03-25
|
||||
**Category:** token
|
||||
**Decision:** Typography system expanded from ~12 to 21 variants organized in 6 categories: Display (5 levels), Heading (6 levels), Body (4 sizes), Label (3 sizes), Caption (2 sizes), Overline (2 sizes). Caption/sm and overline/sm floored at 11px for accessibility.
|
||||
**Affects:** primitive typography tokens, semantic typography tokens, MUI theme, Typography component
|
||||
**Alternatives considered:** Keeping the simpler scale — rejected as user explicitly wanted more variety matching their FA 2.0 Figma type system.
|
||||
|
||||
### D021 — Input uses external label pattern, not MUI floating label
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Input label sits above the input field as a separate element, not as MUI's floating/outlined label that sits on the border. Uses MUI's `InputLabel` with `position: static` and `shrink: true`.
|
||||
**Rationale:** The Figma design shows the label as a distinct element above the input with a 6px gap. The floating label pattern is harder to read and interact with, especially for FA's audience who may be elderly or in distress. External labels have better usability research support for form comprehension.
|
||||
**Affects:** Input component structure, MUI InputLabel styling, no notch in OutlinedInput
|
||||
**Alternatives considered:** MUI's default floating label (outlined variant) — rejected as it doesn't match the Figma design and has usability concerns for the target audience.
|
||||
|
||||
### D022 — Input sizes: medium (48px) and small (40px)
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Input has two sizes: medium (48px, default) and small (40px). Medium aligns with Button large (48px) for search bar pairing. Small aligns with Button medium (40px) for compact layouts.
|
||||
**Rationale:** Figma designed inputs at 64px which is too tall relative to other components and creates misalignment with buttons. 48px meets the 44px touch target minimum and aligns with our Button large. Both sizes sit on the 4px grid.
|
||||
**Affects:** tokens/component/input.json, MUI theme MuiOutlinedInput size overrides
|
||||
**Alternatives considered:** Single size at 64px (Figma original) — rejected as it dwarfs adjacent buttons. Three sizes (sm/md/lg) — rejected as premature; two sizes cover all current form patterns.
|
||||
|
||||
### D023 — Input focus ring uses brand.500 warm gold, not brand.600 copper
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Input focus ring uses brand.500 (#BA834E warm gold) via a double box-shadow (2px white + 4px brand), not the brand.600 copper used for Button focus outlines.
|
||||
**Rationale:** The Figma FA 2.0 design explicitly specifies brand.500 for the input focus ring as an `elevation-special/focus-ring` effect token. The warm gold is softer and more appropriate for form inputs where the focus indicator should be visible but not aggressive. Buttons use brand.600 outline because they need to stand out against coloured backgrounds.
|
||||
**Affects:** MUI theme MuiOutlinedInput focus styles
|
||||
**Alternatives considered:** Using brand.600 (same as Button) — rejected as the Figma explicitly uses brand.500 for inputs.
|
||||
|
||||
### D024 — Input label stays neutral on error/success states
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Input label colour remains `text.secondary` regardless of error/success state. Only the border and helper text change colour.
|
||||
**Rationale:** Per the Figma design. A full-red label would feel alarming, which is inappropriate for FA's sensitive context. The subtle approach (border + helper text colour change) communicates the issue without distress. Users who are already in an emotional state don't need aggressive visual feedback.
|
||||
**Affects:** InputLabel Mui-error and Mui-focused style overrides
|
||||
**Alternatives considered:** Colouring the label red on error — rejected as too aggressive for the audience.
|
||||
|
||||
### D025 — Added startIcon/endIcon convenience props and success state
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Input component adds three features beyond the Figma design: (1) `startIcon` prop for leading icons, (2) `endIcon` prop for trailing icons (convenience wrapper around MUI adornments), (3) `success` boolean prop for validation success state (green border + green helper text). Error-state icons (ErrorOutline) and success-state icons (CheckCircleOutline) are recommended patterns in stories.
|
||||
**Rationale:** Leading icons (email, phone, dollar) are essential for FA's arrangement forms. Success state provides positive feedback after validation. The Figma only had trailing icon, but leading icons are a near-universal production need. The `startIcon`/`endIcon` props are simpler than MUI's `InputAdornment` pattern while remaining compatible with raw adornments via `startAdornment`/`endAdornment`.
|
||||
**Affects:** Input component API, InputAdornment usage, Storybook stories
|
||||
**Alternatives considered:** Only supporting MUI's raw adornment API — rejected as too verbose for the common case. The convenience props are ergonomic while the raw props remain available for complex cases (e.g., password toggle with IconButton).
|
||||
|
||||
### D026 — ProviderCard establishes the molecule pattern
|
||||
**Date:** 2026-03-25
|
||||
**Category:** architecture
|
||||
**Decision:** ProviderCard is the first molecule. Molecules compose existing atoms via `sx` props — no MUI theme overrides. All styling from token CSS variables and theme accessors.
|
||||
**Rationale:** Keeps molecules lightweight and composable. Theme overrides are reserved for atoms where global consistency matters. Molecules are higher-level compositions with more context-specific layouts.
|
||||
**Affects:** All future molecules (VenueCard, MapCard, ServiceOption, etc.)
|
||||
**Alternatives considered:** Adding MuiProviderCard theme overrides — rejected as molecules are page-specific compositions, not reusable primitives.
|
||||
|
||||
### D027 — ProviderCard image is a URL string, not a ReactNode
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** `imageUrl` prop accepts a string rendered as CSS `background-image` with `cover`. Logo is also a URL string rendered as `<img>`.
|
||||
**Rationale:** Simpler API for the common case (CDN URLs). CSS background-image handles aspect ratio cropping automatically. `<img>` for logo supports `alt` text natively for accessibility.
|
||||
**Affects:** ProviderCard, VenueCard, MapCard APIs
|
||||
**Alternatives considered:** ReactNode for image — rejected as over-flexible. A ReactNode slot would allow video/carousel but adds API complexity for a feature we don't need yet.
|
||||
|
||||
### D028 — Logo is 48px (not 75px from Figma)
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** Logo overlay is 48px diameter, not the 75px shown in Figma.
|
||||
**Rationale:** On a ~340-400px card in a list panel, a 75px logo dominates the content area. 48px provides clear brand visibility while leaving sufficient space for the provider name and meta row.
|
||||
**Affects:** providerCard.logo.size token
|
||||
**Alternatives considered:** 75px from Figma — too large for the card width. 64px — still large relative to content.
|
||||
|
||||
### D029 — Footer is built into ProviderCard, not a slot
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** The "Packages from $X >" footer is rendered via a `startingPrice` number prop, not a children/slot pattern.
|
||||
**Rationale:** The footer is structurally identical across all provider cards — warm background, "Packages from" text, price, chevron. Only the price value changes. A slot would add API complexity for no flexibility gain. If footer is omitted (no startingPrice), the bar is simply absent.
|
||||
**Affects:** ProviderCard API, VenueCard may use a similar pattern
|
||||
**Alternatives considered:** children/render prop for footer — rejected as over-engineered for a fixed layout.
|
||||
|
||||
### D030 — Verified is an explicit boolean, not derived from imageUrl
|
||||
**Date:** 2026-03-25
|
||||
**Category:** component
|
||||
**Decision:** `verified` boolean prop controls the visual treatment independently from `imageUrl`/`logoUrl`.
|
||||
**Rationale:** A provider could be verified but have a broken/missing image URL. The boolean is the source of truth from the business layer. Image and logo are only rendered when `verified` is also true, preventing accidental display of unverified providers with images.
|
||||
**Affects:** ProviderCard API, data model expectations
|
||||
**Alternatives considered:** Deriving verified from imageUrl presence — rejected as it couples business logic (partner status) to content availability (image uploaded).
|
||||
|
||||
### D031 — Token access convention: theme accessors for semantic, CSS vars for component
|
||||
**Date:** 2026-03-27
|
||||
**Category:** architecture
|
||||
**Decision:** Two token access methods are both valid, used by tier:
|
||||
- **`theme.palette.*`, `theme.typography.*`, `theme.spacing()`** — for semantic tokens that MUI maps into its theme (palette colours, typography variants, spacing). Used when the MUI theme callback is already available.
|
||||
- **`var(--fa-*)`** CSS variables — for component-tier tokens (badge sizes, card shadows, input dimensions) generated by Style Dictionary but not mapped into the MUI theme. Also acceptable for semantic tokens when the CSS variable form is more ergonomic (e.g., in colour maps, static styles).
|
||||
**Rationale:** The codebase naturally evolved this dual-path pattern. Semantic tokens are mapped into the MUI theme by `src/theme/index.ts`, making `theme.palette.*` the idiomatic MUI access path. Component-tier tokens exist only as CSS variables (Style Dictionary output). Forcing all access through one path would either require mapping every component token into MUI (over-engineering) or abandoning MUI's type-safe theme accessors (losing DX).
|
||||
**Affects:** All component files, `docs/conventions/component-conventions.md`, Badge.tsx (normalized to CSS vars for colour maps)
|
||||
**Alternatives considered:** CSS vars only — rejected because it loses MUI's TypeScript-safe theme API. Theme accessors only — rejected because component tokens aren't in the MUI theme.
|
||||
|
||||
### D032 — FuneralFinder V3 is the production version
|
||||
**Date:** 2026-03-27
|
||||
**Category:** component
|
||||
**Decision:** FuneralFinderV3 is the production widget. V1 and V2 are archived — their Storybook stories moved to `Archive/FuneralFinder V1` and `Archive/FuneralFinder V2`. Code remains in the repo for reference and client walkthroughs.
|
||||
**Rationale:** User chose V3 after reviewing all three. V3 scored highest on usability (clean form, no sequential lock, always-active CTA) while maintaining audit/critique scores (18/20, 33/40). V1 and V2 must remain viewable for client presentations showing the design evolution.
|
||||
**Affects:** FuneralFinder stories (title changes), component-registry (V3 = done, V1/V2 = archived), retroactive review (only V3 gets full treatment)
|
||||
**Alternatives considered:** Deleting V1/V2 — rejected because user needs them for client walkthroughs.
|
||||
|
||||
### D034 — Form error styling uses copper, not red
|
||||
**Date:** 2026-03-29
|
||||
**Category:** token
|
||||
**Decision:** Form error borders and helper text use copper (#B0610F / ColorTextBrand) instead of MUI's default red (#BC2F2F). `palette.error.main` remains red for non-form uses (destructive buttons, system alerts).
|
||||
**Rationale:** FA's grief-sensitive context makes aggressive red inappropriate for form validation. D024 established labels stay neutral on error; D034 extends this to borders and helper text for a fully warm error experience. Copper at 4.8:1 contrast on white meets WCAG AA.
|
||||
**Affects:** src/theme/index.ts (MuiOutlinedInput, MuiFormHelperText, MuiFormLabel overrides), ToggleButtonGroup atom, all page-level error Typography elements
|
||||
**Alternatives considered:** Changing `palette.error.main` globally to copper — rejected because destructive action buttons and system alerts may genuinely need red.
|
||||
|
||||
### D033 — Retroactive review uses P0/P1 only, interleaved with new work
|
||||
**Date:** 2026-03-27
|
||||
**Category:** architecture
|
||||
**Decision:** Existing components are reviewed using a condensed process (normalize → audit → fix P0/P1 only). Review runs as a proactive "morning housekeeping" pass at the start of each session (~30-60 min), then shifts to new component work.
|
||||
**Rationale:** P0/P1 are the issues that affect usability and accessibility. P2/P3 are cosmetic — not worth the risk of changing approved components. Interleaving ensures the foundation is solid before building on it, without dedicating entire sessions to review.
|
||||
**Affects:** Session workflow, CLAUDE.md startup procedure, docs/reference/retroactive-review-plan.md
|
||||
**Alternatives considered:** Dedicated review sessions — rejected as less efficient. Full P0-P3 fixes — rejected as too risky for approved components.
|
||||
|
||||
### D035 — Package sections standardised to Essentials / Optionals / Extras
|
||||
**Date:** 2026-04-06
|
||||
**Category:** component
|
||||
**Decision:** Package data uses three sections: **Essentials** (priced core items), **Optionals** (complimentary inclusions), **Extras** (additional-cost items after the total). Replaces the previous "Complimentary Items" naming.
|
||||
**Rationale:** Matches the real-world package structure from FA's provider data (see reference image). "Optionals" better communicates that these are included-but-not-mandatory items, while "Complimentary" is a price label on individual items, not a section name.
|
||||
**Affects:** PackageDetail stories, ComparisonTable sections, ComparisonPage mobile cards
|
||||
**Alternatives considered:** "Inclusions" instead of "Optionals" — rejected as it overlaps with Essentials (which are also inclusions).
|
||||
|
||||
### D036 — ComparisonCellValue uses discriminated union type
|
||||
**Date:** 2026-04-06
|
||||
**Category:** architecture
|
||||
**Decision:** Cell values in ComparisonTable use a tagged union type (`{ type: 'price' | 'allowance' | 'complimentary' | 'included' | 'poa' | 'unknown' | 'unavailable' }`) rather than flat optional props.
|
||||
**Rationale:** Ensures exhaustive pattern matching in CellValue renderer — the TypeScript compiler catches missing cases. Clearer than a flat `{ price?: number; priceLabel?: string; isAllowance?: boolean }` which has ambiguous combinations. Each value type maps to a distinct visual treatment.
|
||||
**Affects:** ComparisonTable, ComparisonPage mobile card view
|
||||
**Alternatives considered:** Reusing PackageLineItem from PackageDetail — rejected as it conflates "how data is stored" with "how data is displayed". The comparison needs explicit cell state (e.g. "unavailable" vs "unknown").
|
||||
|
||||
### D037 — Mobile comparison uses chip tabs, not horizontal scroll table
|
||||
**Date:** 2026-04-06
|
||||
**Category:** component
|
||||
**Decision:** ComparisonPage renders a chip-based tab rail + single card view on mobile, rather than a horizontally scrollable table.
|
||||
**Rationale:** Wide comparison tables on small screens create "hidden column" problems — users can't see all packages at once and may miss columns. Card view with tabs matches mental model of reviewing one option at a time. Lower cognitive load for FA's grief-sensitive audience. Tab rail provides quick switching. ARIA tablist/tabpanel semantics.
|
||||
**Affects:** ComparisonPage mobile layout
|
||||
**Alternatives considered:** Horizontal scroll table — rejected for poor usability on small screens. Accordion per package — rejected as it hides content behind extra taps.
|
||||
|
||||
### D038 — Recommended package is a separate prop, not mixed into packages array
|
||||
**Date:** 2026-04-06
|
||||
**Category:** architecture
|
||||
**Decision:** ComparisonPage accepts `recommendedPackage` as a separate prop from `packages`. The page merges it as the last column with `isRecommended: true`.
|
||||
**Rationale:** Keeps the user-selected array clean and unambiguous. The recommendation source is explicit (server-side logic). The page controls placement (always last column/tab). Prevents accidental removal of the recommended package by the user (no Remove button).
|
||||
**Affects:** ComparisonPage props, ComparisonTable isRecommended column
|
||||
**Alternatives considered:** Including recommended in the packages array with a flag — rejected as it mixes user selections with system recommendations.
|
||||
|
||||
### D039 — PackageLineItem gains priceLabel for consistency with LineItem
|
||||
**Date:** 2026-04-06
|
||||
**Category:** component
|
||||
**Decision:** Added `priceLabel?: string` to `PackageLineItem` interface in PackageDetail, passed through to LineItem molecule.
|
||||
**Rationale:** LineItem already supports `priceLabel` for custom price text ("Complimentary", "Price On Application", "TBC"). PackageDetail's type was missing this field, forcing workarounds. Adding it enables the Optionals section to display "Complimentary" labels and Extras to show "Price On Application".
|
||||
**Affects:** PackageDetail component + stories, any consumer of PackageLineItem type
|
||||
**Alternatives considered:** None — this was a straightforward type parity fix.
|
||||
@@ -1,985 +0,0 @@
|
||||
# Session log
|
||||
|
||||
This file tracks work completed across Claude Code sessions. Every agent MUST
|
||||
read this file before starting work and update it after completing work.
|
||||
|
||||
> Earlier sessions (2026-03-24 through 2026-03-26d) archived in
|
||||
> `docs/memory/archive/sessions-through-2026-03-26.md`
|
||||
|
||||
## Format
|
||||
|
||||
Each entry follows this structure:
|
||||
```
|
||||
### Session [date] — [brief description]
|
||||
**Agent(s):** [which agents were active]
|
||||
**Work completed:**
|
||||
- [bullet points of what was done]
|
||||
**Decisions made:**
|
||||
- [any design/architecture decisions with brief rationale]
|
||||
**Open questions:**
|
||||
- [anything unresolved that needs human input]
|
||||
**Next steps:**
|
||||
- [what should happen next]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Sessions
|
||||
|
||||
### Session 2026-04-07 — Package comparison iteration (Figma-informed)
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **ComparisonTable major iteration** from Figma feedback:
|
||||
- Dark info card → soft grey info card (surface.subtle, no border), stretches to match card heights, text at top
|
||||
- Provider cards: no logos, floating verified badge (VerifiedOutlinedIcon, consistent with ProviderCard/MiniCard/MapPopup), rating in cards (body2 size)
|
||||
- Separate bordered tables per section (Essentials, Optionals, Extras) with left accent borders (3px brand-500)
|
||||
- Reviews section removed (rating lives in cards)
|
||||
- Horizontal scroll on narrow desktops (minWidth enforcement)
|
||||
- Cards: flex stretch + spacer for CTA bottom-alignment across mixed verified/unverified
|
||||
- Row hover highlight (brand-50), font hierarchy (labels text.secondary, values fontWeight 600)
|
||||
- **ComparisonPage iteration:**
|
||||
- Share + Print buttons in page header (onShare, onPrint props)
|
||||
- Mobile verified badge (VerifiedOutlinedIcon in soft brand Badge)
|
||||
- Mobile section headings with left accent borders
|
||||
- Mobile item rows: 60% max-width for names, inline info icons with nowrap binding
|
||||
- Mobile tab rail: mini Card components (provider name + package name) replacing Chips
|
||||
- Navigation included by default in all stories
|
||||
- **CompareBar simplified:**
|
||||
- Fraction badge (1/3, 2/3, 3/3)
|
||||
- Contextual copy: "Add another to compare" / "Ready to compare"
|
||||
- Removed package names and remove buttons from pill
|
||||
- **Figma integration:**
|
||||
- Created `/capture-to-figma` skill — captures Storybook stories to Parsons Figma file
|
||||
- Created `/figma-ideas` skill — fetches Figma designs and proposes adaptations
|
||||
- Successfully captured ComparisonPage to Figma (node 6041-25005)
|
||||
- Applied user's Figma tweaks (node 6047-25005) back to code
|
||||
- **Cleanup:** Removed Figma capture script from preview-head.html, Prettier formatting pass
|
||||
|
||||
**Decisions made:**
|
||||
- Info card uses surface.subtle (not dark), stretches to match cards — less visually competing
|
||||
- Verified badge uses VerifiedOutlinedIcon (consistent with rest of system), floating above cards
|
||||
- Rating lives in card headers, no separate Reviews table
|
||||
- Section tables separated with left accent borders (3px brand-500)
|
||||
- Mobile tab rail uses mini Cards (provider + package name) not Chips
|
||||
- Share/Print are optional props on ComparisonPage
|
||||
|
||||
**Next steps:**
|
||||
- Commit all work
|
||||
- Wire CompareBar into PackagesStep/ProvidersStep (state management)
|
||||
- Consider comparison state persistence (URL params or context)
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-04-06b — Package comparison feature
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **PackageDetail fix (D039):** Added `priceLabel?: string` to `PackageLineItem` interface, passed through to LineItem. Updated stories to use Essentials/Optionals/Extras sections with realistic funeral data (D035). "Complimentary Items" → "Optionals".
|
||||
- **CompareBar molecule (new):** Floating comparison basket pill. Fixed bottom, slide-up/down animation. Badge count + provider names + remove × buttons + Compare CTA. Max 3 user packages. Disabled CTA when <2. Inline `role="alert"` error for max-reached. Mobile: compact count + CTA only. Audit: 18/20 (P2s fixed: error visible on mobile, removed redundant aria-disabled).
|
||||
- **ComparisonTable organism (new):** CSS Grid side-by-side comparison. Sticky header cards with provider logo/name/location/rating + package name + price + CTA. Row-merged sections via `buildMergedSections` union algorithm. 7 cell value types via discriminated union (D036). Recommended column with warm bg + Badge. Verified → "Make Arrangement", unverified → "Make Enquiry". ARIA `role="table"` + `role="row"` + `role="columnheader"` + `role="cell"`. Desktop only. Audit: 17/20 (P2s fixed: aria-label on recommended column, rowheader on section headings, token-based zebra striping).
|
||||
- **ComparisonPage page (new):** WizardLayout (wide-form). Desktop: full ComparisonTable. Mobile: chip tab rail (`role="tablist"`) + single MobilePackageCard (`role="tabpanel"`). Recommended package as separate prop, merged as last column/tab. Back link, help bar.
|
||||
- **Stories:** 6 CompareBar stories (Default, SinglePackage, ThreePackages, WithError, Empty, Interactive), 5 ComparisonTable stories (Default, TwoPackages, WithRecommended, MixedVerified, MissingData), 5 ComparisonPage stories (Default, TwoPackages, WithRecommended, MobileView, FullPage with Navigation).
|
||||
- **Quality gates:** TypeScript ✓, ESLint ✓, Storybook build ✓. CompareBar audit 18/20, ComparisonTable audit 17/20.
|
||||
|
||||
**Decisions made:**
|
||||
- D035: Package sections standardised to Essentials/Optionals/Extras
|
||||
- D036: ComparisonCellValue uses discriminated union for exhaustive rendering
|
||||
- D037: Mobile comparison uses chip tabs + card view, not horizontal scroll table
|
||||
- D038: Recommended package is a separate prop, always additional to user selections
|
||||
- D039: PackageLineItem gains priceLabel for consistency with LineItem molecule
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- Visual review in Storybook (user + Playwright screenshots)
|
||||
- Wire CompareBar into PackagesStep (state management for comparison basket)
|
||||
- Consider adding CompareBar to WizardLayout as a slot or portal
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-04-06 — Retroactive review completion
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Phase 1 atoms complete:** Audited Typography (18/20, no P0/P1) and Badge (15/20, P0 `role="status"` determined false positive — would create unwanted aria-live on static labels)
|
||||
- **Phase 2 molecules complete:** Normalized all 9 molecules — displayName ✓, forwardRef ✓, ARIA ✓, no hardcoded colours. Flagged AddOnOption/ProviderCard ARIA issues reviewed and determined false positives (Switch is semantic control; ProviderCard has `...rest` passthrough)
|
||||
- **Phase 3 organisms complete:** Normalized 5 active organisms. Audited Navigation (15/20, no real P0/P1 — focus-visible from MUI theme, CSS vars D031-compliant) and ServiceSelector (17/20, **fixed P0: added `aria-required` to radiogroup**)
|
||||
- **Phase 4 preflight:** TypeScript ✓, ESLint ✓, Prettier ✓, Storybook build ✓
|
||||
- **Review plan updated:** All phases marked done. Only `/typeset` deferred (low risk)
|
||||
|
||||
**Decisions made:**
|
||||
- Badge `role="status"` rejected: static status labels shouldn't be aria-live regions
|
||||
- AddOnOption `role="checkbox"` rejected: Switch is the semantic control, Card click is convenience
|
||||
- CSS var usage in organisms is D031-compliant (CSS vars acceptable for semantic tokens per D031)
|
||||
|
||||
**Open questions:**
|
||||
- From 2026-04-01: Which HomePage version (V3 or V4) is production?
|
||||
|
||||
**Next steps:**
|
||||
- User has components to change/build — shifting to that work
|
||||
|
||||
**Work completed (continued):**
|
||||
- **MiniCard molecule (new + iterated):** Compact vertical card. Image + verified icon-only badge (copper circle, top-right) + title (h6, 2-line max with tooltip on truncation) + meta row + price + badges + chips. Hierarchy: title → meta → price → badges → chips. 3 component tokens. Audit: 20/20.
|
||||
- **MapPin atom (new + redesigned):** Two-line label map marker: name (bold, truncated 180px) + "From $X" (centred, semibold 600). Name optional for price-only variant. Verified = brand palette, unverified = grey. Active inverts + scale. Padding bumped from 8px to 12px for readability. Pure CSS. role="button" + keyboard + focus ring.
|
||||
- **MapPopup molecule (new + iterated):** Clickable floating card (onClick). Image + verified icon badge (matches MiniCard) + name (1-line, tooltip on truncation) + meta + price. Hierarchy matches MiniCard. No-image fallback shows inline verified icon + text. Nub + drop-shadow. 260px wide.
|
||||
- **Component tokens:** miniCard.json and mapPin.json added to Style Dictionary, rebuilt CSS/JS/TS outputs (407 declarations total).
|
||||
|
||||
**Decisions made:**
|
||||
- MiniCard uses `h6` for title (smaller than ProviderCard's `h5`), `caption` for meta, `body2` for price
|
||||
- MiniCard verified badge is icon-only circle (not text chip) — compact, matches map popup
|
||||
- MapPin redesigned from price-only pill to two-line name+price label — transparency and clarity
|
||||
- MapPin price centred under name — left-aligned looked unbalanced (visually reviewed)
|
||||
- MapPin price weight 600 (semibold) — 500 was too thin at 11px
|
||||
- MapPin padding 12px (was 8px) — names were tight against edges
|
||||
- MapPopup whole card clickable — removed "View details" link
|
||||
- MapPopup name 1-line limit (was 2) with tooltip — tighter for map context
|
||||
- Chips in MiniCard rendered as soft default Badges (no interactive Chip atom) for visual simplicity
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-04-01 — FuneralFinder V4, HomePage V3/V4, Footer restyle
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **FuneralFinder V4 (new organism):** Based on V2 with major changes:
|
||||
- 3 numbered steps only (lookingTo, planningFor, funeralType) — location is ungated, no step number
|
||||
- No heading/subheading — compact widget for embedding in heroes
|
||||
- Refined step indicators: 48px circles matching input height, outline-to-fill + tick animation, no connector lines
|
||||
- Labels above, circle + input on same row centred
|
||||
- Location field full-width, disabled until step 3 complete
|
||||
- "Search" CTA, inline copper error messages per field (D034)
|
||||
- Archived in Storybook under Archive/FuneralFinder V4
|
||||
- **FuneralFinder V3 updates:**
|
||||
- Removed default subheading (now optional)
|
||||
- Heading font weight bumped from 400 → 600 (semibold) for more presence
|
||||
- Heading copy: "Find your local providers"
|
||||
- CTA: "Search Local Providers"
|
||||
- **HomePage V1 archived:** Original split-hero layout moved to Archive/HomePage V1
|
||||
- **HomePage V2 archived:** Full-bleed hero version broken out as Archive/HomePage V2
|
||||
- **HomePage V3 (new, archived):** Based on V2 with:
|
||||
- hero-3.png background image
|
||||
- Updated hero copy + bullet-point subheading ("Transparent pricing · No hidden fees · Arrange 24/7")
|
||||
- Real venue photos in discover section provider cards
|
||||
- Map placeholder image from brandassets
|
||||
- Scrolling partner logo bar (9 transparent logos, greyscale, edge-to-edge, continuous loop)
|
||||
- CTA section: warm gradient bg, text button, no dividers, wider container
|
||||
- Increased section spacing throughout (~25% more breathing room)
|
||||
- Hero top padding increased 40%
|
||||
- **HomePage V4 (new, archived):** Same as V3 but uses FuneralFinder V4 via `finderSlot` prop. Wider container (620px) for stepped form.
|
||||
- **HomePage component updates:**
|
||||
- Added `finderSlot` prop — allows swapping the finder widget without changing the component
|
||||
- Increased spacing: hero heading/subtext gap, finder-to-discover gap, all section padding
|
||||
- Map container: absolute positioning for dynamic height matching card stack
|
||||
- CTA section: gradient bg (brand.100 → surface.warm), text button, no dividers
|
||||
- Partner logos: lighter treatment (40% opacity, brightness lift), 48→55px height, 96px gap, no hover interaction
|
||||
- **Footer restyle:** Changed from dark espresso (brand.950) to light grey (surface.subtle) matching the header. All text colours flipped to dark-on-light. Logo no longer needs inverse filter.
|
||||
|
||||
**Decisions made:**
|
||||
- FuneralFinder V4 step indicators use 48px circles (same height as inputs) for visual alignment
|
||||
- Location field in V4 is gated behind step 3 completion but not numbered
|
||||
- Inline error messages replace single bottom error — each field shows its own copper-coloured message
|
||||
- Footer matches header bg colour (surface.subtle) for visual consistency
|
||||
- Partner logos: only transparent PNGs/WebPs used, opaque logos excluded
|
||||
- `finderSlot` prop added to HomePage for widget flexibility without component duplication
|
||||
|
||||
**Open questions:**
|
||||
- HomePage V4 finder width may need further adjustment — looked narrow in Storybook preview panel (620px container, may need 680-720px)
|
||||
- Which HomePage version (V3 with FuneralFinderV3 or V4 with FuneralFinderV4) will be the production version?
|
||||
- FuneralFinder V4 step indicator design — user liked the direction but may want further iteration
|
||||
|
||||
**Next steps:**
|
||||
- Resolve HomePage V4 finder width — test at wider viewport or increase container
|
||||
- Decide on production HomePage + FuneralFinder version
|
||||
- Build next components/pages as needed
|
||||
- Phase 4 remaining: /typeset sample, /preflight full codebase
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-31d — Filters, control bars, UnverifiedProviderStep, HomePage V2
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Phase 4 /adapt reviews:** Ran responsive adaptation audits on Navigation, Footer, ProviderCard, VenueCard. Fixed P0/P1 touch target issues in Navigation (hamburger + drawer items minHeight 44px) and Footer (all links minHeight 44px, tagline responsive maxWidth). ProviderCard/VenueCard skipped — meta rows aren't interactive, card itself is the touch target.
|
||||
- **ProvidersStep structured filters:** Replaced generic `ProviderFilter[]` chip array with `ProviderFilterValues` interface containing 5 filter controls inside FilterPanel/DialogShell:
|
||||
- **Location:** Autocomplete `multiple` + `freeSolo` with chip-in-input pattern (real estate site UX — chip sits inside the search field with X to clear)
|
||||
- **Service tradition:** Autocomplete with type-to-search, 21 options ('None' first, then alphabetical traditions)
|
||||
- **Funeral type:** Chip multi-select with wrapping layout (6 types from spec)
|
||||
- **Verified providers / Online arrangements:** Switch toggles
|
||||
- **Price range:** Dual-knob slider + compact editable inputs (matching CoffinsStep)
|
||||
- **FilterPanel molecule updates:** "Done" → "Apply", "Clear all" moved to footer as "Reset filters" text button
|
||||
- **DialogShell padding:** px 3 → 5 (12px → 20px) for breathing room
|
||||
- **Filter panel UX iterations (3 rounds):**
|
||||
- Section headings: `labelLg` + `fontWeight: 600` for visual hierarchy
|
||||
- Price inputs: compact `fontSize: 0.875rem` + tighter padding
|
||||
- Funeral type chips: wrap layout (not horizontal scroll) — stays within bounds
|
||||
- Price slider: `px: 2.5` accommodates MUI thumb radius, no overflow
|
||||
- Active filter count includes location search; reset clears search too
|
||||
- **VenueStep structured filters:** Same FilterPanel pattern as ProvidersStep with venue-specific controls:
|
||||
- Location (chip-in-input), Venue type (7 chips: Chapel, Church, Cathedral, Outdoor Venue, Hall/Room, Mosque, Temple), Additional services (Video Streaming + Photo Display switches), Service tradition (autocomplete)
|
||||
- **Control bar (both pages):** Below search, single line:
|
||||
- `[Filters]` left, `[↕ Recommended]` right (compact menu button with dropdown)
|
||||
- Sort options: Recommended, Nearest, Price: Low to High, Price: High to Low
|
||||
- Results count on own line below with breathing room
|
||||
- **List/Map view toggle:** Floating overlay in top-left of map panel (paper bg + shadow). Text-labelled: "List" / "Map" with icons. Follows Airbnb/Domain pattern — contextually placed where the map lives.
|
||||
- New types: `ProviderSortBy`, `VenueSortBy`, `ListViewMode`, `VenueFilterValues`, `VenueTypeOption`
|
||||
- **UnverifiedProviderStep (new page):** list-detail layout for scraped provider listings. Left: ProviderCardCompact + "Listing" badge + available info + verified recommendations. Right: warm header band + enquiry CTA. 4 story variants (Default, MinimalData, NoData, NoRecommendations). Graceful degradation when data missing.
|
||||
- **HomePage V2:** Full-bleed hero with `parsonshero.png`, FuneralFinder inside hero (overlaps into white below), "See what you'll discover" map+ProviderCardCompact section, stripped features (no cards/circles — just icons+text), editorial alternating testimonials, minimal FAQ accordion, simplified CTA. Multiple iteration rounds on hero positioning.
|
||||
- New types: `TrustStat`, `FeaturedProvider`, `ProviderDetail`, `RecommendedProvider`
|
||||
|
||||
**Decisions made:**
|
||||
- "Service tradition" as the label for religion/faith filter — neutral, user-centric, covers religious and non-religious
|
||||
- 'None' as first tradition option
|
||||
- Location uses Autocomplete chip-in-input pattern (Domain/realestate.com.au style)
|
||||
- Funeral type chips wrap (stack) rather than horizontal scroll — clearer at dialog width
|
||||
- DialogShell px: 5 is a global change — all dialogs get more breathing room
|
||||
- FilterPanel footer: "Reset filters" + "Apply" replaces header "Clear all" + footer "Done"
|
||||
- List/Map toggle lives on the map panel (floating overlay), not in the control bar — frees space, contextually placed
|
||||
- Sort uses compact menu button (not TextField select) — same visual weight as Filters button
|
||||
- Unverified providers use list-detail layout (same as PackagesStep) for consistency
|
||||
- Unverified CTA is "Make an Enquiry" (not "Make an Arrangement") — honest framing
|
||||
- HomePage V2 hero: text top-aligned, FuneralFinder inside hero with negative mb overlap
|
||||
- Features section: no cards/circles — just icons + text for authentic feel
|
||||
- Hero gradient: 55% opacity at top for readability on bright sky
|
||||
|
||||
**Open questions:**
|
||||
- HomePage V2 still a first pass — may iterate further on discover section, testimonials, etc.
|
||||
- UnverifiedProviderStep paused — may revisit for enquiry form fields
|
||||
|
||||
**Next steps:**
|
||||
- Continue user feedback on remaining pages
|
||||
- Phase 4 remaining: `/typeset` sample, `/preflight` full codebase
|
||||
- Add progress bar + cart stories to more page stories
|
||||
- Update component-registry.md with UnverifiedProviderStep
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-31c — PaymentStep/ConfirmationStep review + progress bar + CartButton
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Organism normalize pass (Phase 3):** Scanned all 6 organisms. Fixed FuneralFinderV3 transition timing (200ms → 150ms ease-in-out), added autodocs tag to V3 stories. Navigation audit 18/20, ServiceSelector 20/20.
|
||||
- **Navigation P1 fix:** Logo wrapper changed from `div[role=link]` to proper `<a>` tag for keyboard accessibility.
|
||||
- **PaymentStep feedback (5 items):** Divider under subheading, lock icon alignment, ToggleButtonGroup `align` + `direction` props (centre-aligned payment options, vertical payment method stack), checkbox alignment fix.
|
||||
- **ToggleButtonGroup atom enhanced:** New `align` (start/center) and `direction` (row/column) props. Description text bumped from `text.secondary` to `text.primary`.
|
||||
- **SummaryStep:** Save button → text variant (matches other pages), centred.
|
||||
- **Cross-page heading spacing:** All wizard pages `mb: 1` → `mb: 2` on display3 heading.
|
||||
- **ConfirmationStep redesign:** Animated SVG tick (circle draws then checkmark), "What happens next" warm card with bullet points, contact phone as prop, link-based secondary actions.
|
||||
- **VenueStep + ProvidersStep:** Sticky search bar padding fix, off-white bg behind card lists.
|
||||
- **IntroStep, CemeteryStep, CrematoriumStep, DateTimeStep:** Dividers under subheadings.
|
||||
- **CoffinsStep:** h4 heading (matches list layouts), sidebar headings h5 → h6.
|
||||
- **CartButton molecule (new):** Outlined pill trigger with receipt icon + "Your Plan" + formatted total in brand colour. Click opens DialogShell with items grouped by section via LineItem, total row, empty state. Mobile collapses to icon + price.
|
||||
- **WizardLayout:** Removed STEPPER_VARIANTS whitelist — stepper bar now renders on all variants when props provided. Stepper centred at 700px max-width, cart hugs right.
|
||||
- **StepIndicator:** Desktop label fontSize bumped to 0.875rem for readability.
|
||||
- **Prop threading:** progressStepper + runningTotal added to DateTimeStep, VenueStep, SummaryStep, PaymentStep.
|
||||
- **Style Dictionary:** Auto-generate tokens.d.ts on build, fixed TS unused imports.
|
||||
|
||||
**Decisions made:**
|
||||
- ToggleButtonGroup `align` and `direction` are opt-in props — existing usages unchanged
|
||||
- ConfirmationStep contact phone is now a prop (default 1800 987 888), no more hardcoded placeholder
|
||||
- WizardLayout stepper bar shows on ANY variant when props provided (StepperBar returns null when empty)
|
||||
- CartButton is a molecule (not organism) — self-contained trigger + dialog, same pattern as FilterPanel
|
||||
- Stepper bar layout: stepper centred at maxWidth 700px, cart hugs right edge
|
||||
|
||||
**Open questions:**
|
||||
- PaymentStep CTA is right-aligned — all other pages use full-width. Should it match?
|
||||
- Progress bar stories should be added to more page stories (currently only DateTimeStep has them)
|
||||
|
||||
**Next steps:**
|
||||
- Continue user feedback/edits on remaining pages
|
||||
- Add progress bar + cart to remaining page stories
|
||||
- Retroactive review Phase 3 organisms: Navigation P2s still pending (hardcoded fontSize, drawer width)
|
||||
- Update component-registry.md with CartButton
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-31b — CoffinDetailsStep rewrite + AdditionalServicesStep split
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **CoffinDetailsStep rewrite** — two-panel detail-toggles layout with gallery + specs (left), name + description + colour swatches + allowance-aware pricing + CTA (right). Colour selection doesn't affect price. Allowance logic: fully covered / partially covered / no allowance.
|
||||
- **SummaryStep rewrite** — visual cart layout replacing accordion text lists:
|
||||
- Arrangement details section at top (arranger, deceased, tradition, dates, times)
|
||||
- Compact image cards for provider, venue, crematorium, coffin with location pins
|
||||
- Allowance display: "Included in your package" (fully covered) vs price/allowance/remaining breakdown
|
||||
- Checklist for included services, priced list for extras (consistent tick logic)
|
||||
- Share dialog: "Share this plan" opens DialogShell with multi-email input + confirmation
|
||||
- Full-width CTA, deposit deferred to PaymentStep
|
||||
- **AdditionalServicesStep split into two pages:**
|
||||
- **IncludedServicesStep (new)** — services included in the package at no cost. Dressing, viewing (with same-venue sub-option inside card), prayers/vigil, funeral announcement.
|
||||
- **ExtrasStep (new)** — optional paid extras for lead generation. Catering, music (flat inline live musician toggle + musician type), coffin bearing (toggle + bearer preference radio), newspaper notice. POA support via `priceLabel`. Tally of priced selections.
|
||||
- **AddOnOption molecule enhanced:**
|
||||
- `children` prop — sub-options render inside the card boundary (below divider) when checked, eliminating nested card "Russian doll" pattern
|
||||
- `priceLabel` prop — custom text like "Price on application" in brand copper italic
|
||||
- **AdditionalServicesStep removed** — replaced by the two new pages
|
||||
- All quality checks passing (TypeScript, ESLint, Prettier)
|
||||
- Playwright visual verification of all key scenarios
|
||||
|
||||
**Decisions made:**
|
||||
- Split AdditionalServicesStep into two pages for clearer UX distinction between free inclusions and paid extras
|
||||
- Sub-options render inside parent card (flat hierarchy) instead of nested cards
|
||||
- Coffin bearing changed from always-visible radio to toggle + sub-options (consistent with other items)
|
||||
- `bearing` field split into `bearing: boolean` + `bearerType` for toggle pattern
|
||||
- Extras page is lead-gen: signals interest, not firm commitment. Director follows up.
|
||||
- POA items show "Price on application" in brand copper italic
|
||||
- Copy refined through brand lens — no transactional language ("toggle on"), warm professional tone
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- Continue page feedback: PaymentStep, ConfirmationStep
|
||||
- Retroactive review Phase 3 (organisms) still pending
|
||||
- Batch a11y fix (aria-describedby + aria-invalid) deferred
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-31b — CoffinDetailsStep rewrite: product detail layout
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **CoffinDetailsStep complete rewrite** — transformed to match VenueDetailStep two-panel pattern:
|
||||
- **Left panel:** ImageGallery (hero + thumbnails), product details as semantic `dl` list (bold label above value)
|
||||
- **Right panel (sticky):** coffin name (h1), description, colour swatch picker, price with allowance-aware display, CTA, save-and-exit
|
||||
- **Colour picker:** circular swatches (36px), `aria-pressed`, controlled via `selectedColourId`/`onColourChange`, does not affect price
|
||||
- **Allowance pricing logic:** fully covered (allowance >= price) → "Included in your package allowance — no change to your plan total." / partially covered → shows "$X package allowance applied" + "+$Y to your plan total" in brand colour / no allowance → price only with extra spacing to CTA
|
||||
- **Removed:** info bubble (redundant with allowance impact text), `priceNote` prop, `termsText` prop, old horizontal specs grid, `CoffinAllowance` type
|
||||
- **Added:** `CoffinColour` type, `allowanceAmount` prop, `onAddCoffin` callback (replaces `onContinue`)
|
||||
- **A11y:** fixed heading hierarchy (price as `<p>` not `<h5>`, Product details as `<h2>`) — 0 violations
|
||||
- **Stories:** FullyCovered, PartiallyCovered, NoAllowance, NoColours, Minimal, PrePlanning, Loading
|
||||
- **Playwright visual verification** of all key scenarios
|
||||
- All quality checks passing (TypeScript, ESLint, Prettier)
|
||||
|
||||
**Decisions made:**
|
||||
- Allowance impact is computed from `allowanceAmount` vs `coffin.price` — no remaining balance tracking (out of scope)
|
||||
- Info bubble removed from detail page (redundant) — kept on CoffinsStep browsing page
|
||||
- Product details as single-column stacked `dl` (label above value) — more readable than grid
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- Continue page feedback: AdditionalServicesStep, SummaryStep, PaymentStep, ConfirmationStep
|
||||
- Retroactive review Phase 3 (organisms) still pending
|
||||
- Batch a11y fix (aria-describedby + aria-invalid) deferred
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-31a — CoffinsStep rewrite: grid-sidebar ecommerce layout
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **CoffinsStep complete rewrite** — transformed from wide-form card grid into a two-column ecommerce layout matching the live site pattern:
|
||||
- **Layout:** `grid-sidebar` with viewport-locked independent scrolling (sidebar scrollbar on hover, grid always scrollable)
|
||||
- **Sidebar:** heading, conditional allowance info bubble, category menu with expandable subcategories (Collapse animation, chevron rotation), dual-knob price range slider with editable text inputs (commit on blur/Enter), sort by dropdown (popularity, price asc/desc), clear all filters link, save-and-exit link at bottom
|
||||
- **Grid:** 3-col coffin card grid with `CoffinCard` internal component — thumbnail hover preview (hover swaps main image, leave reverts), equal-height cards via flex layout, subtle background for white-bg product photos, "Most Popular" badge, colour count text
|
||||
- **Navigation:** card click fires `onSelectCoffin(id)` to navigate to CoffinDetailsStep — no Continue button
|
||||
- **Pagination:** 20 coffins per page max (`pageSize` prop, enforced via slice)
|
||||
- **WizardLayout `grid-sidebar` update** — wider sidebar (28%), `overflowX: hidden` (no horizontal scroll), `overflowY: auto` at all breakpoints, responsive viewport-lock (desktop only)
|
||||
- **Removed:** `selectedCoffinId`, `CoffinsStepErrors`, `CoffinPriceRange`, `onContinue`, `loading` props
|
||||
- **Added:** `onSelectCoffin`, `CoffinSortBy`, `pageSize`, `minPrice`/`maxPrice`, `thumbnails`/`colourCount` on Coffin, `children` on `CoffinCategory`
|
||||
|
||||
**Decisions made:**
|
||||
- Card click navigates directly to details (no selection + continue pattern) — matches ecommerce browsing UX
|
||||
- Categories support one level of subcategories — parent click loads all and expands children, child click refines
|
||||
- Price slider with editable text inputs — commits on blur/Enter to avoid per-keystroke re-renders
|
||||
- 20 coffins per page default — enforced in component via slice
|
||||
- Allowance info bubble is conditional (omit prop = no bubble) — some packages don't have coffin allowances
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- Continue page feedback: AdditionalServicesStep, SummaryStep, PaymentStep, ConfirmationStep
|
||||
- Retroactive review Phase 3 (organisms) still pending
|
||||
- Batch a11y fix (aria-describedby + aria-invalid) deferred
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-30e — Page feedback: VenueServices, Crematorium, Cemetery rewrites
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **VenueServicesStep (new page):** Built step 7c — venue-specific service toggles after VenueDetailStep. Compact venue card at top, availability notices (info cards for unavailable services), AddOnOption toggles with maxDescriptionLines for "Read more" expansion, conditional tally showing total of selected priced services. Flow: VenueStep → VenueDetailStep → VenueServicesStep.
|
||||
- **AddOnOption price colour fix:** Changed from `text.secondary` (grey) to `color="primary"` (copper) for consistency with all other price displays in the system.
|
||||
- **CrematoriumStep rewrite:** Completely rewritten to match live site. Two variants based on funeral type:
|
||||
- Service & Cremation: stacked crematorium card (image top, details below) + witness Yes/No/Decide later ToggleButtonGroup
|
||||
- Cremation Only: stacked card + "Cremation Only" badge + "Included in Package" info notice, no witness question
|
||||
- Removed: multi-card selection grid, priority dropdown, special instructions, crematoriums array prop
|
||||
- Card iterated from compact horizontal → more generous horizontal → stacked layout based on user feedback
|
||||
- **CemeteryStep rewrite:** Rewritten to match live site:
|
||||
- RadioGroups replaced with ToggleButtonGroups (Yes/No/Not sure)
|
||||
- Card selection grid replaced with freetext search input (Input atom with search icon)
|
||||
- `searchSlot` prop for parent to inject Google Places or geocoding autocomplete
|
||||
- Removed static `cemeteries` array prop and `CemeteryOption` type
|
||||
- Progressive disclosure preserved: own plot → locate it; no plot → preference? → search
|
||||
|
||||
**Decisions made:**
|
||||
- Venue services belong on a separate page (not inline on VenueDetailStep or in a dialog) due to content volume per service (long descriptions, future images)
|
||||
- Crematorium is always pre-selected by provider — no multi-select needed, just confirmation
|
||||
- "Decide later" / "Not sure" options added as explicit third choice on questions where users may be uncertain — grief-sensitive pattern
|
||||
- Cemetery search should use real location search (Google Places style), not a static dropdown — we don't maintain a cemetery database
|
||||
- Stacked card layout (image top) works better than compact horizontal for single confirmation cards with long text
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- Continue page feedback: CoffinsStep, AdditionalServicesStep, SummaryStep, PaymentStep, ConfirmationStep
|
||||
- Retroactive review Phase 3 (organisms) still pending
|
||||
- Batch a11y fix (aria-describedby + aria-invalid) deferred
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-30d — Steps 8-15 consistency pass
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Consistency pass across Steps 8-15** — aligned all remaining wizard steps with the conventions established during the Steps 1-6 feedback iteration:
|
||||
- **Subheading variant:** CrematoriumStep, CoffinDetailsStep changed from `body2` → `body1` (match IntroStep/DateTimeStep centered-form convention)
|
||||
- **Subheading spacing:** CrematoriumStep, CemeteryStep, CoffinDetailsStep, AdditionalServicesStep, SummaryStep, PaymentStep all changed from `mb: 4` → `mb: 5`
|
||||
- **Section dividers:** CrematoriumStep gained 3 `<Divider>` between question sections (crematorium → witness, conditional priority, special instructions)
|
||||
- **Link atom:** PaymentStep terms links and ConfirmationStep phone number changed from `Box component="a"` → `Link` atom
|
||||
- **CoffinsStep:** No changes needed (wide-form layout has its own spacing convention)
|
||||
- **Audited CrematoriumStep (15/20) and PaymentStep (16/20)** — findings are pre-existing, not introduced by the pass
|
||||
- **Visual verification:** Playwright screenshots of CrematoriumStep, PaymentStep, ConfirmationStep, AdditionalServicesStep, SummaryStep — all pass
|
||||
|
||||
**Decisions made:**
|
||||
- Centered-form heading convention now formally: `display3` → `body1` subheading → `mb: 5` gap (documented via consistent implementation across all 10+ centered-form steps)
|
||||
- Wide-form layout (CoffinsStep) keeps its own tighter spacing convention (`body2` + `caption`, `mb: 3`)
|
||||
|
||||
**Open questions:**
|
||||
- **Checkbox atom:** PaymentStep uses MUI Checkbox directly — only form control without an FA atom wrapper. Create Checkbox atom?
|
||||
- **aria-describedby/aria-invalid:** All wizard steps lack error field association. Batch normalize fix recommended.
|
||||
- **Retroactive review Phase 2.2** still pending (audit priority molecules: ServiceOption, AddOnOption, ProviderCardCompact)
|
||||
|
||||
**Also completed (same session):**
|
||||
- **Checkbox atom created:** New FA wrapper (forwardRef, displayName, stories: Default/States/TermsAgreement/Checklist). MuiCheckbox theme overrides (warm gold checked, focus ring, disabled muted). PaymentStep updated to import from atom.
|
||||
- **Retroactive review Phase 2.2 complete:** Audited ServiceOption (13/20), AddOnOption (14/20), ProviderCardCompact (15/20). Fixed:
|
||||
- AddOnOption: added `aria-disabled` when disabled (P1)
|
||||
- ProviderCardCompact: added `maxLines={1}` on name (P2)
|
||||
- ServiceOption: price uses `labelLg` variant instead of h6 + hardcoded fontWeight (P1)
|
||||
- Note: audit agents flagged false P0s (AddOnOption "double handler", ServiceOption "role collision") — verified both are correctly handled by existing `stopPropagation` and prop spread order in Card atom
|
||||
|
||||
**Also completed (continued same session):**
|
||||
- **DateTimeStep:** Swapped date TextField to Input atom (was missed in session 30b)
|
||||
- **VenueStep rewrite:** Simplified to click-to-navigate (like ProvidersStep) — removed Continue, selection state, inline detail, service toggles
|
||||
- **VenueDetailStep (new page):** Detail-toggles layout with scrollable left panel (ImageGallery, description, features grid, location map placeholder, address, informational service cards) and right panel (name, meta icons, price + offset note, Add Venue CTA, address, religion chips)
|
||||
- **CoffinDetailsStep:** Switched from centered-form to detail-toggles layout (image left, specs/price/CTA right)
|
||||
- **WizardLayout detail-toggles overhaul:** Viewport-locked with independent panel scroll, maxWidth 1200px centered, generous padding (px:5), back link inside left panel
|
||||
- **WizardLayout list-map scroll fix:** Removed top padding gap between nav and sticky search, heading scrolls away while search/filters stay pinned with divider border
|
||||
- **ImageGallery molecule (new):** Hero image + landscape thumbnail strip (4:3 ratio), hover to preview, click to select, keyboard accessible, wired into VenueDetailStep and CoffinDetailsStep
|
||||
- **Checkbox atom (new):** FA wrapper with warm gold theming, PaymentStep updated
|
||||
- **Retroactive review Phase 2.2:** Audited ServiceOption (13/20), AddOnOption (14/20), ProviderCardCompact (15/20), fixed P0/P1s
|
||||
|
||||
**Next steps:**
|
||||
- Continue page feedback from user: CrematoriumStep, CemeteryStep, CoffinsStep, AdditionalServicesStep, SummaryStep, PaymentStep, ConfirmationStep
|
||||
- Venue service selection step (new page — toggles moved from VenueDetailStep)
|
||||
- Batch a11y fix: aria-describedby + aria-invalid across all wizard steps (deferred per user)
|
||||
- Retroactive review Phase 3: organisms normalize + audit
|
||||
- Update component registry with new components (ImageGallery, Checkbox, VenueDetailStep)
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-30c — HomePage build + Chromatic + Story to Design setup
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Story to Design agent:** Helped user install and run the story.to.design agent on Arch Linux (extracted from .deb, installed webkit2gtk dependency). Agent connects Storybook to Figma plugin.
|
||||
- **Chromatic setup:** Installed chromatic, published Storybook to Chromatic CDN. Set visibility to public for shareable links. Updated `package.json` chromatic script with `--build-script-name=build:storybook`.
|
||||
- **HomePage component built:** Full marketing landing page at `src/components/pages/HomePage/`
|
||||
- 7 sections: Hero, FuneralFinder widget (overlapping card), Partner Logos carousel, Features (4-card grid), Reviews/Testimonials, CTA Banner, FAQ accordion
|
||||
- Composes FuneralFinderV3 organism, Navigation + Footer via props
|
||||
- CSS-only infinite scroll logo carousel with prefers-reduced-motion
|
||||
- Feature cards with warm circular icon backgrounds
|
||||
- Full a11y: section landmarks, aria-labelledby, heading hierarchy
|
||||
- Grief-sensitive copy (quieter pass applied)
|
||||
- **Quality gates run:** /critique (32/40), /audit (16/20), /quieter (all pass)
|
||||
- **Design iteration:** Multiple rounds of visual refinement using Playwright screenshots
|
||||
- Reduced oversized typography (display1 → display3 for hero, display2 → h2 for sections)
|
||||
- Reserved serif fonts for hero + CTA only, sans-serif for all other section headings
|
||||
- Tightened spacing, reduced section padding
|
||||
- Feature cards: compact padding, warm circular icon backgrounds
|
||||
- Fixed unicode rendering bugs in copy
|
||||
|
||||
**Decisions made:**
|
||||
- Serif display fonts reserved for hero heading and CTA banner only — all other section headings use Montserrat (h2/h3)
|
||||
- Feature card icons wrapped in warm circular backgrounds (brand.50 bg, 56px diameter)
|
||||
- HomePage is a page component (not a template) — does not use WizardLayout
|
||||
- Chromatic published URL is the shareable Storybook link for stakeholders
|
||||
|
||||
**Open questions:**
|
||||
- Homepage is first-pass only — user will return to iterate later
|
||||
- Partner logo placeholder images need real assets
|
||||
- Hero image slot needs real photography
|
||||
- CTA banner click destination needs clarification (scroll to widget vs wizard entry)
|
||||
|
||||
**Next steps:**
|
||||
- Resume arrangement wizard page feedback from VenueStep (Step 7) onwards — Steps 1-6 done in previous session
|
||||
- Remaining pages: VenueStep, CrematoriumStep, CemeteryStep, CoffinsStep, CoffinDetailsStep, AdditionalServicesStep, SummaryStep, PaymentStep, ConfirmationStep
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-30b — Page feedback iteration (Steps 1-6) + DialogShell
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **IntroStep (Step 1):** Static subheading (removed dynamic text change on selection), ToggleButtonGroup top-left alignment fix
|
||||
- **ProvidersStep (Step 2):** Heading reduced to h4 "Find a funeral director", SearchBar → location TextField with pin icon, FilterPanel moved below search right-aligned, map fill fix (height:100% → flex:1), hover scrollbar on left panel
|
||||
- **VenueStep (Step 7):** Same consistency fixes as ProvidersStep (h4, location icon, filter layout, map fill, results count format)
|
||||
- **PackagesStep (Step 3):** Removed budget filter + "Most Popular" badge + mobile Continue button. Added grouped packages pattern ("Matching your preferences" / "Other packages from [Provider]" with brand accent bars). `onArrange` replaces `onContinue`. Clickable provider card (`onProviderClick`). Heading to h4.
|
||||
- **DateTimeStep (Step 6):** display3 heading (centered-form consistency). Name fields swapped from MUI TextField to Input atom (external label, no clipping). Multiple preferred dates (up to 3, progressive disclosure). Removed service tradition/religion field. Dividers between question sections.
|
||||
- **DialogShell atom:** New shared dialog container (header + optional back + close, scrollable body, optional footer). Audited 17→19/20, P1s fixed (focus management, sx pattern).
|
||||
- **FilterPanel refactored:** Popover → DialogShell (centered Dialog with backdrop)
|
||||
- **ArrangementDialog refactored:** Now composes DialogShell for consistent chrome
|
||||
- **PreviewStep + AuthGateStep removed:** Consolidated into ArrangementDialog (D-E)
|
||||
- **WizardLayout:** ListMapLayout left panel gets thin scrollbar visible on hover
|
||||
|
||||
**Decisions made:**
|
||||
- Heading convention: display3 for centered-form pages, h4 for narrow panels (list-map, list-detail)
|
||||
- DialogShell is the standard popup container — all site dialogs compose it
|
||||
- Service tradition removed from DateTimeStep — flows from provider/package selection, confirmed on summary
|
||||
- "Service tradition" is the preferred terminology (not "religion" or "religious style")
|
||||
- Package grouping pattern: matched vs other, with brand accent bar section labels
|
||||
- FilterPanel uses Dialog (not Popover) for filter controls
|
||||
|
||||
**Open questions:**
|
||||
- Provider profile popup contents — user will provide details later
|
||||
- Heading convention (display3 vs h4) should be documented as a decision
|
||||
|
||||
**Next steps:**
|
||||
- **Resume page feedback from VenueStep (Step 7) onwards** — Steps 1-6 are done
|
||||
- Remaining pages to review: VenueStep, CrematoriumStep, CemeteryStep, CoffinsStep, CoffinDetailsStep, AdditionalServicesStep, SummaryStep, PaymentStep, ConfirmationStep
|
||||
- Homepage layout work (user priority — separate task)
|
||||
- Input atom clipping: audit remaining pages for MUI TextField → Input atom swap where labels clip
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-30a — Tooling upgrades + workflow evaluation
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Storybook addons:** Added `@storybook/addon-storysource` (story source code panel) and `@storybook/addon-a11y` (real-time axe-core accessibility checks)
|
||||
- **Playwright MCP:** Installed `@playwright/mcp` and registered as MCP server. Enables Claude Code to take screenshots of Storybook for visual verification. Available from next session.
|
||||
- **Workflow evaluation:** Comprehensive analysis of current capabilities, identified core gap (Claude Code cannot see visual output), researched solutions
|
||||
- **Antigravity research:** Investigated Google Antigravity IDE for visual polish workflow. Installed on system. Created `GEMINI.md` project rules file. User decided to pause on Antigravity for now and continue with Claude Code + Playwright MCP approach.
|
||||
- **GEMINI.md:** Created project rules file for Antigravity IDE, mirroring key conventions from CLAUDE.md (token access, atomic tiers, no hardcoded values)
|
||||
|
||||
**Decisions made:**
|
||||
- Playwright MCP is the primary solution for visual verification gap — enables Claude Code to screenshot Storybook stories and self-correct visual issues
|
||||
- Antigravity available as secondary tool for visual tweaks but not primary workflow
|
||||
- Claude Code remains the primary tool for architectural/structural work due to custom skills, memory system, and accumulated project context
|
||||
|
||||
**Open questions:**
|
||||
- User has refinement feedback from previous session that was partially overlooked — to be addressed next session
|
||||
- Some items from the user's original feedback across 15 steps were missed when compressed into D-A through D-H decisions
|
||||
|
||||
**Next steps:**
|
||||
- Restart session to activate Playwright MCP
|
||||
- User to provide refinement feedback
|
||||
- Use Playwright MCP to visually verify changes as they're made
|
||||
- Address remaining P1s from previous session (radiogroup keyboard nav, dialog mobile fullscreen)
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-29e — Feedback iteration Batches 1 & 2
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Batch 1: Atom + Template Foundation**
|
||||
- ToggleButtonGroup: label-to-options spacing `mb: 1→2`, top-align content `flex-start`, fixed selected border CSS specificity (added `&.Mui-selected` in grouped selector)
|
||||
- Heading standardisation: all 6 split-layout steps changed from `h4` → `display3` (ProvidersStep, PackagesStep, PreviewStep, VenueStep, CoffinsStep, CoffinDetailsStep) per D-A
|
||||
- DateTimeStep: normalised section gaps (scheduling fieldset `mb: 3→4`)
|
||||
- CrematoriumStep: added subheading for consistency, normalised witness section `mb: 3→4`
|
||||
- PackagesStep + DateTimeStep: fixed input label clipping (`pt: 0.5` on TextField containers)
|
||||
- **Batch 2: List-Map Layout Rework (D-B)**
|
||||
- WizardLayout ListMapLayout: 420px fixed left column, `flex: 1` right panel
|
||||
- Back link rendered inside left panel (not above split) — eliminates gap above map
|
||||
- LAYOUT_MAP type updated to accept `backLink` prop for list-map variant
|
||||
- ProvidersStep + VenueStep: sticky header (heading + search + filters pinned at top of scrollable left panel)
|
||||
- **Batch 3: FilterPanel molecule + integration (D-C, D-F)**
|
||||
- New FilterPanel molecule: Popover trigger with active count badge, Clear all, Done actions
|
||||
- ProvidersStep: inline chips → FilterPanel Popover alongside search bar
|
||||
- VenueStep: same pattern, filter chips in Popover
|
||||
- CoffinsStep (D-F): grid-sidebar → wide-form (full-width 4-col grid), filters in Popover
|
||||
- WizardLayout: added `wide-form` variant (maxWidth lg, single column) for card grids
|
||||
- FilterPanel stories: Default, WithActiveFilters, SelectFilters, CustomLabel
|
||||
- **Batch 4: Step Simplifications (D-D, D-G)**
|
||||
- ProvidersStep (D-D): removed selection state, Continue button, radiogroup pattern. Clicking a provider card triggers navigation directly. Stories updated.
|
||||
- CoffinDetailsStep (D-G): removed all customisation (handles, lining, nameplate, OptionSection, ProductOption/CoffinDetailsStepValues types). Simplified to coffin profile + Continue CTA. Changed from detail-toggles to centered-form layout. Stories simplified.
|
||||
- Updated CoffinDetailsStep index.ts re-exports
|
||||
- **Batch 5: ArrangementDialog organism (D-E)**
|
||||
- New ArrangementDialog organism: MUI Dialog with two internal steps
|
||||
- Step 1 (preview): ProviderCardCompact, package summary with sections/items/total, "What happens next" checklist
|
||||
- Step 2 (auth): SSO buttons, email, progressive disclosure for details, verification code, terms
|
||||
- Parent controls step state + auth form values; dialog has back arrow and close button
|
||||
- Stories: Default (full flow), AuthStep, AuthDetails, PrePlanning
|
||||
- PreviewStep + AuthGateStep kept for now, to be deprecated once dialog is wired in
|
||||
|
||||
**Decisions made:**
|
||||
- All 8 iteration decisions now implemented: D-A through D-H
|
||||
|
||||
**Quality passes:**
|
||||
- Ran 3 parallel audits (FilterPanel, ArrangementDialog, all reworked steps)
|
||||
- FilterPanel: 4 P0 + 2 P1 fixed (forwardRef, useId, aria-controls, dialog role, label prop, scroll)
|
||||
- ArrangementDialog: 3 P0 + 2 P1 fixed (forwardRef, focus management, aria-live, semantic tokens, Link atom)
|
||||
- Sticky headers: responsive padding match + top breathing room (pt: 2)
|
||||
- ProvidersStep: role="list", semantic map token
|
||||
- VenueStep: aria-label on search, semantic map token
|
||||
- CoffinDetailsStep: form wrapper added
|
||||
|
||||
**Remaining P1/P2 (for next session):**
|
||||
- VenueStep/CoffinsStep radiogroup arrow-key navigation (P1)
|
||||
- ArrangementDialog step number badge hardcoded font size/weight (P1)
|
||||
- ArrangementDialog mobile fullscreen treatment (P1)
|
||||
- CoffinDetailsStep centered-form width may be tight for coffin images (P2)
|
||||
- CTA alignment inconsistency VenueStep vs CoffinsStep/CoffinDetailsStep (P2)
|
||||
- ArrangementDialog missing story variants: verify, loading, errors, overflow (P2)
|
||||
|
||||
**Open questions:**
|
||||
- PreviewStep + AuthGateStep: deprecate/remove once ArrangementDialog fully replaces them in the flow
|
||||
- User to review all steps in Storybook and report any visual issues still present
|
||||
|
||||
**Next steps:**
|
||||
- User review in Storybook — note any remaining visual issues
|
||||
- Fix remaining P1s (radiogroup keyboard nav, dialog mobile fullscreen)
|
||||
- Wire ArrangementDialog into PackagesStep flow
|
||||
- Component registry updates for FilterPanel + ArrangementDialog
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-29c — Grooming pass: critique/harden/polish all 15 steps
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Full grooming pass across all 15 wizard steps** — applied critique (UX design review), harden (edge cases/error states), and polish (visual alignment/copy/code) frameworks.
|
||||
- **[P0] CrematoriumStep bug fix:** `<option>` elements replaced with `<MenuItem>` — the MUI `<TextField select>` requires MenuItem children, not native option elements. The priority dropdown was non-functional.
|
||||
- **[P1] Double-submit prevention:** Added `if (!loading) onContinue()` guard to all form `onSubmit` handlers across steps 1, 5, 6, 7, 8, 9, 10, 11, 12, 14 (10 steps with forms). Prevents keyboard Enter re-submission during async loading.
|
||||
- **[P1] Accessibility — aria-busy:** Added `aria-busy={loading}` to all form elements so screen readers announce processing state.
|
||||
- **[P1] Error colour normalisation:** Replaced `color="error"` (red #BC2F2F) with `var(--fa-color-text-brand)` (copper #B0610F) across 7 steps (ProvidersStep, PackagesStep, VenueStep, CrematoriumStep, CemeteryStep, CoffinsStep, PaymentStep). Per D024, FA uses warm copper for errors rather than aggressive red.
|
||||
- **[P2] Grief-sensitive copy:** "Has the person died?" → "Has this person passed away?" (IntroStep). "About the person who died" → "About the person who has passed" (DateTimeStep).
|
||||
- **[P2] Results count copy:** "Showing results from X providers" → "X providers found" (ProvidersStep).
|
||||
- **[P2] Empty state guidance:** Added actionable guidance text to empty states in ProvidersStep, PackagesStep, VenueStep, CoffinsStep ("Try adjusting..." copy).
|
||||
- **Steps that passed with no issues:** PreviewStep (4), SummaryStep (13), ConfirmationStep (15) — all clean.
|
||||
- **IntroStep critique score: 35/40 (Good)** — full heuristic scoring completed as reference.
|
||||
- **D034 implemented:** Form error styling unified to copper end-to-end. MuiOutlinedInput error border/ring, MuiFormHelperText error text, MuiFormLabel error state (neutral per D024), ToggleButtonGroup error border — all now use copper (#B0610F). `palette.error.main` remains red for non-form uses.
|
||||
- **Tagged `v0.1-wizard-groomed`** — safe rollback point before user review checkpoint.
|
||||
- **Roadmap documented** in persistent memory (`project_roadmap.md`) with 9 phases, checkpoint gates, and guiding principles.
|
||||
|
||||
**Decisions made:**
|
||||
- D034: Form error styling uses copper across theme (MuiOutlinedInput, MuiFormHelperText, MuiFormLabel, ToggleButtonGroup). `palette.error.main` stays red for destructive buttons/system alerts.
|
||||
- User review checkpoint required before integration — tagged `v0.1-wizard-groomed` as rollback point.
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- Feedback iteration Batch 1 (next session)
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-29d — User review checkpoint + iteration planning
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **D034 implemented:** Form error copper styling unified across theme (MuiOutlinedInput, MuiFormHelperText, MuiFormLabel, ToggleButtonGroup).
|
||||
- **Tagged `v0.1-wizard-groomed`** — safe rollback point before feedback iteration.
|
||||
- **Roadmap documented** in persistent memory (`project_roadmap.md`).
|
||||
- **User review checkpoint completed.** User reviewed all 15 steps in Storybook and provided detailed feedback across every step.
|
||||
- **Iteration plan created** at `.claude/plans/zany-jingling-lynx.md` — 7 batches, ~6-8 sessions estimated.
|
||||
- **All 8 design decisions resolved** (D-A through D-H): display3 headings everywhere, 420px fixed left column, Popover filters, click-to-navigate (no Continue buttons on selection steps), two-step modal for preview+auth, full-width coffin grid, remove coffin customisation for now, defer map pins.
|
||||
|
||||
**Key feedback themes:**
|
||||
- ToggleButtonGroup: spacing tight, content misaligned, selected border not showing (CSS specificity bug)
|
||||
- List-map layout: needs fixed-width left column, scrollable list with fixed header, no gap above map
|
||||
- New FilterPanel component needed (reusable across providers, venues, coffins)
|
||||
- PreviewStep + AuthGateStep consolidation into two-step modal
|
||||
- CoffinDetailsStep: remove customisation, simplify to details + CTA
|
||||
- Several copy and spacing issues across steps
|
||||
|
||||
**Decisions made:**
|
||||
- D-A: `display3` heading everywhere (brand warmth)
|
||||
- D-B: 420px fixed left column in list-map layout
|
||||
- D-C: FilterPanel uses Popover (MVP), Drawer for mobile later
|
||||
- D-D: Click-to-navigate on ProvidersStep (remove selection state + Continue)
|
||||
- D-E: Remove standalone PreviewStep + AuthGateStep, use two-step ArrangementDialog
|
||||
- D-F: CoffinsStep full-width grid with FilterPanel button
|
||||
- D-G: Remove coffin customisation, note as future enhancement
|
||||
- D-H: Map pins deferred
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- Start Batch 1: Atom + Template Foundation (ToggleButtonGroup fixes, heading standardisation, spacing normalisation)
|
||||
- Plan file: `.claude/plans/zany-jingling-lynx.md`
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-29b — Wizard steps 5-15 (complete flow)
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Step 5 — AuthGateStep:** Centered-form, 3 progressive sub-steps (SSO/email → details → verify). Phone optional when email-only. Benefit framing ("Save your plan"). Audit 18/20, P1 fixed (responsive name fields).
|
||||
- **Step 6 — DateTimeStep:** Centered-form, two fieldset sections (name + scheduling). Grief-sensitive labels ("Their first name"). Date/time radios + Autocomplete for religion (22 options). Save-and-exit CTA.
|
||||
- **Step 7 — VenueStep:** Venue card grid (1-2 col) with search/filters. Inline venue detail (Collapse) with features + religions. Service toggles (photo, streaming, recording) via AddOnOption. VenueCard extended with selected + ARIA passthrough props.
|
||||
- **Step 8 — CrematoriumStep:** Single crematorium confirmation card (most common) or multi-card grid. Witness question personalised with deceased name. Special instructions via progressive disclosure textarea.
|
||||
- **Step 9 — CemeteryStep:** Triple progressive disclosure (have plot? → choose cemetery? → card grid). Dependent field resets. "Provider can arrange this" shortcut.
|
||||
- **Step 10 — CoffinsStep:** 3-col card grid with category/price filters. "Most Popular" badge (Rec #10). Pagination support. Australian terminology ("coffin").
|
||||
- **Step 11 — CoffinDetailsStep:** Coffin profile (image + specs grid) + 3 product option RadioGroups (handles, lining, nameplate) with branded selected state. Price: "Included" or "+$X".
|
||||
- **Step 12 — AdditionalServicesStep:** Merged from optionals + extras (Rec #2). Section 1: complimentary (dressing, viewing, prayers, announcement). Section 2: paid (catering, music, bearing, newspaper). Multi-level progressive disclosure.
|
||||
- **Step 13 — SummaryStep:** Accordion sections with edit buttons, dl/dt/dd definition lists, total bar (aria-live), share button. Pre-planning: "Save your plan" / at-need: "Confirm".
|
||||
- **Step 14 — PaymentStep:** ToggleButtonGroup for plan (full/deposit) + method (card/bank). PayWay iframe slot. Bank transfer details display. Terms checkbox. Security reassurance.
|
||||
- **Step 15 — ConfirmationStep:** Terminal page, no back/progress. At-need: "submitted" + callback info. Pre-planning: "saved" + return-anytime. Muted success icon, next-steps links.
|
||||
|
||||
**Approach:** Same as previous session — first pass build + quick audit + P0/P1 fixes only. Grooming pass comes later.
|
||||
|
||||
- **Layout fixes:** Corrected 3 steps that had wrong WizardLayout variants:
|
||||
- VenueStep: centered-form → **list-map** (venue cards left, map slot right — matches ProvidersStep)
|
||||
- CoffinsStep: centered-form → **grid-sidebar** (filter sidebar left, card grid right)
|
||||
- CoffinDetailsStep: centered-form → **detail-toggles** (coffin profile left, option selectors right)
|
||||
|
||||
**Decisions made:**
|
||||
- VenueCard extended with selected/ARIA props (same pattern as ProviderCard from step 2)
|
||||
- CoffinDetailsStep uses OptionSection helper component for DRY RadioGroup rendering
|
||||
- SummaryStep uses Accordion not Paper for sections (per spec's collapsible requirement)
|
||||
- PaymentStep uses slot pattern for PayWay iframe (cardFormSlot prop)
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- All 15 wizard steps are now first-pass complete (steps 1-15) with correct layouts
|
||||
- Grooming pass: /critique, /harden, /polish, /normalize across all steps
|
||||
- Retroactive review backlog still pending
|
||||
- Integration: routing, state management, GraphQL queries
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-29 — Wizard Phase 0 through Phase 4 (foundation + steps 1-4)
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Phase 0 — Foundation components:**
|
||||
- WizardLayout template: 5 layout variants, nav slot, sticky help bar, back link, progress stepper + running total, `<main>` landmark
|
||||
- Collapse atom: thin MUI Collapse wrapper with unmountOnExit
|
||||
- ToggleButtonGroup atom: exclusive single-select with fieldset/legend a11y, FA brand styling
|
||||
- **Phase 1 — IntroStep (step 1):**
|
||||
- Centered-form layout, forWhom + hasPassedAway with progressive disclosure
|
||||
- Auto-sets hasPassedAway="no" for "Myself", grief-sensitive copy adapts
|
||||
- Audit 18→20/20 after fixes (`<main>` landmark, `<form>` wrapper)
|
||||
- **Phase 2 — ProvidersStep (step 2):**
|
||||
- List-map split: provider cards w/ radiogroup + search + filter chips (left), map slot (right)
|
||||
- ProviderCard extended with selected prop + HTML/ARIA passthrough
|
||||
- Audit 18/20, P1 fixed (radio on focusable Card)
|
||||
- **Phase 3 — PackagesStep (step 3):**
|
||||
- List-detail split: ProviderCardCompact + budget filter + ServiceOption list (left), PackageDetail (right)
|
||||
- "Most Popular" badge, mobile Continue button
|
||||
- **Phase 4 — PreviewStep (step 4):**
|
||||
- Informational review, "What happens next" numbered checklist
|
||||
- Pre-planning variant shows "Explore other options" tertiary CTA
|
||||
|
||||
**Approach:** First pass of all steps (build + quick audit + P0/P1 fixes only), then grooming pass (critique/harden/polish/normalize) across the full flow.
|
||||
|
||||
**Decisions made:**
|
||||
- Templates at `src/components/templates/`, Pages at `src/components/pages/`
|
||||
- ProviderCard/ServiceOption: ARIA passthrough for radiogroup patterns
|
||||
- First-pass approach: build all steps, then groom — user confirmed
|
||||
|
||||
**Open questions:**
|
||||
- None
|
||||
|
||||
**Next steps:**
|
||||
- Step 5 (Auth Gate) — centered-form layout, account creation/login
|
||||
- Continue through remaining steps (6-18)
|
||||
- Retroactive review backlog still pending
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-27b — Retroactive review Phase 1 + 2.1, wizard planning
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Retroactive review (morning housekeeping):**
|
||||
- Phase 1.1: Atoms normalize — 3 fixes (Input spacing, Card focus token, unused import)
|
||||
- Phase 1.2: Atom audits — Button 20/20, Input 20/20, Card 18→20/20 (2 P1 fixes: keyboard activation + responsive padding)
|
||||
- Phase 2.1: Molecules normalize — 7 fixes (StepIndicator timing/spacing/font, ProviderCardCompact star colour + icon size)
|
||||
- **Wizard flow documentation review:**
|
||||
- Read flow-spec.md (854 lines), flow-definition.yaml (616 lines), 3 representative step YAMLs
|
||||
- Saved reference memories for flow documentation structure and project context
|
||||
- **Layout analysis:**
|
||||
- Analysed 5 layout reference images in /documentation/layouts/
|
||||
- Identified 5 layout variants: Centered Form, List+Map, List+Detail, Grid+Sidebar, Detail+Toggles
|
||||
- Mapped each layout to specific wizard steps
|
||||
- Saved layout reference to memory
|
||||
- **Implementation plan:**
|
||||
- Created comprehensive plan at .claude/plans/validated-brewing-matsumoto.md
|
||||
- Phase 0 (foundation): WizardLayout template, Collapse atom, ToggleButtonGroup atom
|
||||
- Phases 1–7: Steps in build order with component dependencies
|
||||
- ~11 new components, ~16 sessions estimated
|
||||
- Plan approved by user, updated with layout variants
|
||||
|
||||
**Decisions made:**
|
||||
- Step pages live at `src/components/pages/` (new atomic tier)
|
||||
- CardSelectionGrid extracted after step 3 (not upfront)
|
||||
- Build from specs, Figma for structural shape only
|
||||
- Steps are pure presentation (props in, callbacks out) — no routing/state/GraphQL yet
|
||||
|
||||
**Open questions:**
|
||||
- Hardcoded fontWeight on price typography varies across molecules — still unresolved from normalize
|
||||
|
||||
**Next steps:**
|
||||
- Start Phase 0: Build WizardLayout template (5 variants), Collapse atom, ToggleButtonGroup atom
|
||||
- Then Phase 1: Step 1 (Intro) — first wizard step
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-27b (earlier) — Retroactive review Phase 1 + 2.1
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Phase 1.1 — Atoms normalize:** Scanned all 11 atoms across 7 dimensions. Fixed 3 issues: Input raw px spacing → MUI units, Card focus-visible token → CSS var, removed unused Theme import.
|
||||
- **Phase 1.2 — Atom audits (high priority):** Button 20/20, Input 20/20, Card 18/20 → fixed 2 P1s → 20/20.
|
||||
- Card P1 fix: Added Enter/Space keyboard activation for interactive cards (WCAG 2.1.1)
|
||||
- Card P1 fix: Responsive padding — 16px mobile / 24px desktop (convention alignment)
|
||||
- **Phase 2.1 — Molecules normalize:** Scanned all 8 molecules across 7 dimensions. Fixed 7 issues:
|
||||
- StepIndicator: transition 300ms → 150ms, raw px → MUI spacing, borderRadius → token, mobile font 10px → 11px (D020 floor)
|
||||
- ProviderCardCompact: star colour → warning.main (match ProviderCard), meta icon 16px → 14px (match tier)
|
||||
|
||||
**Decisions made:**
|
||||
- None (all fixes are convention enforcement, no new decisions)
|
||||
|
||||
**Open questions:**
|
||||
- Hardcoded fontWeight on price typography varies across molecules (500 vs 600) — intentional design variation or normalize?
|
||||
- Remaining atom audits (Typography, Badge, Chip, Switch, Radio, IconButton, Divider, Link) — all low/medium priority wrappers, likely 20/20. Run if time permits.
|
||||
|
||||
**Next steps:**
|
||||
- Phase 2.2: Audit priority molecules (ServiceOption, AddOnOption, ProviderCardCompact)
|
||||
- Phase 3: Organisms normalize + audit (Navigation, ServiceSelector, FuneralFinderV3)
|
||||
- Phase 4: Cross-cutting (adapt, typeset, preflight)
|
||||
- New component work as user directs
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-27a — Workflow improvement (5-phase infrastructure upgrade)
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- **Phase 1A:** Archived session log — moved 25 old sessions to `docs/memory/archive/sessions-through-2026-03-26.md`, trimmed active log from 1096 to 91 lines
|
||||
- **Phase 1B:** Documented token access convention as D031 — `theme.palette.*` for semantic tokens, `var(--fa-*)` for component tokens. Fixed Badge.tsx colour map inconsistency (unified to CSS vars). Updated component-conventions.md.
|
||||
- **Phase 2:** Added ESLint v9 (flat config) + Prettier. Installed `eslint`, `@eslint/js`, `typescript-eslint`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `eslint-plugin-jsx-a11y`, `eslint-config-prettier`, `prettier`. Ran initial format pass across all 54 .tsx files. Fixed 5 empty interface warnings (Switch, Radio, Divider, IconButton, Link). Added `lint`, `lint:fix`, `format`, `format:check` scripts.
|
||||
- **Phase 3:** Created 7 new impeccable-adapted skills: `/polish`, `/harden`, `/normalize`, `/clarify`, `/typeset`, `/quieter`, `/adapt`. Downloaded Vercel reference docs (web-design-guidelines, react-best-practices). Updated `/audit` and `/review-component` with optional Vercel references. Total skills: 19.
|
||||
- **Phase 4:** Added Husky v9 + lint-staged for pre-commit automation. ESLint + Prettier auto-run on staged files. Updated `/preflight` skill with ESLint and Prettier checks (now 8 checks total).
|
||||
- **Phase 5:** Added Vitest v4 + jsdom + @testing-library/react. Created `vitest.config.ts` and test setup. Created `/write-tests` skill for test generation guidance. Added `test` and `test:watch` scripts. Note: `@storybook/test-runner` deferred — requires Storybook 10+ (we have 8).
|
||||
|
||||
**Decisions made:**
|
||||
- D031: Token access convention — theme accessors for semantic, CSS vars for component (see decisions-log)
|
||||
- ESLint story files exempt from `react-hooks/rules-of-hooks` and `no-console` (Storybook render pattern)
|
||||
- Empty `interface extends` changed to `type =` for ESLint compliance (5 wrapper atoms)
|
||||
- Storybook test-runner deferred until Storybook upgrade to v10
|
||||
- Prettier printWidth set to 100 (matching observed code style)
|
||||
|
||||
**Also completed:**
|
||||
- Created `docs/reference/component-lifecycle.md` — 10-stage quality gate sequence (build → QA → polish → present → iterate → normalize → preflight → commit)
|
||||
- Created `docs/reference/retroactive-review-plan.md` — plan to review 30+ existing components (~3.5 sessions)
|
||||
- Updated `/build-atom`, `/build-molecule`, `/build-organism` to include internal QA stages automatically
|
||||
- Added lifecycle reference as CLAUDE.md critical rule #8
|
||||
|
||||
**Open questions:**
|
||||
- Storybook upgrade to v10 — would unlock `@storybook/test-runner` for CI test execution
|
||||
- FuneralFinder version decision (v1/v2/v3) — needed before retroactive review of organisms
|
||||
- Review depth — P0/P1 only (faster) or include P2?
|
||||
|
||||
**Next steps (pick up in next session):**
|
||||
- Start retroactive review: `/normalize atoms` → `/audit` high-priority atoms
|
||||
- Interleave with new component work if preferred
|
||||
- Use `/write-tests` on interactive components as time permits
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-26f — FuneralFinder v3 build + polish
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- Created FuneralFinderV3 — clean vertical form based on user's Figma layout (5919:29445), restyled to FA design system
|
||||
- Two side-by-side StatusCards (Immediate Need default-selected / Pre-planning), stack on mobile
|
||||
- Standard card container (surface.raised, card shadow) — initially built with glassmorphism, user redirected to standard palette
|
||||
- Overline section labels (text.secondary) for "How Can We Help", "Funeral Type", "Location"
|
||||
- Standard outlined fields (white bg, neutral border, brand border on focus, no focus ring per user request)
|
||||
- Location input with LocationOnOutlined pin icon
|
||||
- CTA "Find Funeral Directors →" always active — validates on click, scrolls to first missing field
|
||||
- Dividers after header and before CTA for visual rhythm
|
||||
- Funeral type options: same as V2 + "Show all options"
|
||||
- WAI-ARIA roving tabindex on radiogroup, aria-labelledby via React.useId()
|
||||
- Semantic tokens throughout (border-brand, surface-warm, text-brand, interactive-focus, text-disabled)
|
||||
- Error messages conditionally rendered in aria-live regions (brand copper tone — gentle validation)
|
||||
- First pass scored Critique 33/40, Audit 13/20 → iterated on all findings → re-audit 18/20
|
||||
- Polish pass: revised copy, fixed spacing, defaults, label rename
|
||||
|
||||
**Decisions made:**
|
||||
- Status cards replace V2's step-circle + dropdown — simpler, more visual, side-by-side on desktop
|
||||
- Standard design system styling (user clarified Figma was for structure only, not colour scheme)
|
||||
- "Immediate Need" selected by default — most common use case, status error essentially unreachable
|
||||
- Section renamed from "Current Status" (programmatic) to "How Can We Help" (warm, human)
|
||||
- Copy: "A recent loss or one expected soon" — "expected soon" differentiates from pre-planning gently
|
||||
- Copy: "Planning ahead for yourself or a loved one" — "planning ahead" reinforces non-urgency
|
||||
- No sequential unlock — all fields accessible immediately
|
||||
- CTA always active — validates on click, scrolls to missing field
|
||||
- Form simplified to 3 fields (status, funeral type, location) vs V2's 4
|
||||
- Focus ring suppressed on Select/Input per user requirement — status cards retain focus-visible
|
||||
- Error colour uses text.brand (copper) not feedback.error (red) — intentional for funeral context
|
||||
|
||||
**Open questions:**
|
||||
- Location autocomplete integration still pending across all versions
|
||||
- Decision: V1 vs V2 vs V3 for production
|
||||
|
||||
**Next steps:**
|
||||
- User to review final V3 in Storybook
|
||||
- If V3 chosen: location autocomplete, possible further refinements
|
||||
|
||||
---
|
||||
|
||||
### Session 2026-03-26e — FuneralFinder v2 polish + consistency fixes
|
||||
|
||||
**Agent(s):** Claude Opus 4.6 (1M context)
|
||||
|
||||
**Work completed:**
|
||||
- Fixed location input styling to match select fields (border color, hover, disabled, error states)
|
||||
- Added `active` prop to StepCircle — step 1 uses brand-500 primary fill by default
|
||||
- Aligned Input with full selectSx overrides (bgcolor, disabled opacity+dashed, error border)
|
||||
- Investigated systemic Input vs Select visual differences — confirmed issue is component-local overrides, not theme
|
||||
|
||||
**Decisions made:**
|
||||
- Custom field styling kept within FuneralFinderV2 (intentional divergence from theme for this component's design)
|
||||
- Step 1 circle uses primary fill since it's always active — visual "start here" signal
|
||||
|
||||
**Next steps:**
|
||||
- v2 is feature-complete and polished — ready for user review in Storybook
|
||||
- Decision pending: v1 vs v2 for production
|
||||
- If v2 chosen: add location autocomplete, write flow logic reference doc
|
||||
|
||||
---
|
||||
@@ -1,288 +0,0 @@
|
||||
# Token registry
|
||||
|
||||
Master reference of all design tokens. Updated by the token-architect agent
|
||||
whenever tokens are created or modified. Other agents reference this to find
|
||||
the correct token for any design property.
|
||||
|
||||
## How to use this file
|
||||
|
||||
- **token-architect**: Update this file whenever you create/modify tokens
|
||||
- **component-builder**: Reference this file to find the correct token for any CSS property
|
||||
- **story-writer**: Reference this file to document which tokens a component uses
|
||||
|
||||
## Primitives
|
||||
|
||||
### Colours
|
||||
|
||||
**Brand (warm gold/copper)** — `tokens/primitives/colours.json`
|
||||
| Token path | Value | Description |
|
||||
|-----------|-------|-------------|
|
||||
| color.brand.50 | #FEF9F5 | Lightest warm tint — warm section backgrounds |
|
||||
| color.brand.100 | #F7ECDF | Light warm — hover backgrounds |
|
||||
| color.brand.200 | #EBDAC8 | Warm light — secondary backgrounds |
|
||||
| color.brand.300 | #D8C3B5 | Warm beige (swatch) — surface warmth |
|
||||
| color.brand.400 | #D0A070 | Mid gold (swatch) — secondary interactive |
|
||||
| color.brand.500 | #BA834E | **Base brand** (swatch) — primary CTA |
|
||||
| color.brand.600 | #B0610F | Rich copper (swatch) — hover, brand links |
|
||||
| color.brand.700 | #8B4E0D | Deep copper — active states |
|
||||
| color.brand.800 | #6B3C13 | Dark brown — bold accents |
|
||||
| color.brand.900 | #51301B | Chocolate (swatch) — deep emphasis |
|
||||
| color.brand.950 | #251913 | Espresso (swatch) — darkest brand |
|
||||
|
||||
**Sage (cool grey-green)** — `tokens/primitives/colours.json`
|
||||
| Token path | Value | Description |
|
||||
|-----------|-------|-------------|
|
||||
| color.sage.50 | #F2F5F6 | Lightest sage — cool backgrounds |
|
||||
| color.sage.100 | #E3EAEB | Light sage — hover states |
|
||||
| color.sage.200 | #D7E1E2 | (swatch) — light cool surface |
|
||||
| color.sage.300 | #C8D4D6 | Mid-light sage — dividers |
|
||||
| color.sage.400 | #B9C7C9 | (swatch) — mid sage |
|
||||
| color.sage.500 | #8EA2A7 | Base sage — secondary content |
|
||||
| color.sage.600 | #687D84 | Dark sage — secondary text |
|
||||
| color.sage.700 | #4C5B6B | (swatch) — secondary buttons |
|
||||
| color.sage.800 | #4C5459 | (swatch) — supplementary text |
|
||||
| color.sage.900 | #343C40 | Very dark sage |
|
||||
| color.sage.950 | #1E2528 | Near-black cool |
|
||||
|
||||
**Neutral (true grey)** — `tokens/primitives/colours.json`
|
||||
| Token path | Value | Description |
|
||||
|-----------|-------|-------------|
|
||||
| color.neutral.50-950 | #FAFAFA–#0A0A0B | Full grey scale for text, borders, UI |
|
||||
| color.neutral.800 | #2C2E35 | (swatch) — **Primary text colour** |
|
||||
|
||||
**Feedback hues** — `tokens/primitives/colours.json`
|
||||
| Token path | Value | Description |
|
||||
|-----------|-------|-------------|
|
||||
| color.red.50-950 | #FEF2F2–#3D0E0E | Error/destructive states |
|
||||
| color.amber.50-950 | #FFF9EB–#331F00 | Warning/caution states |
|
||||
| color.green.50-950 | #F0F7F0–#0F2A0F | Success/positive states |
|
||||
| color.blue.50-950 | #EFF6FF–#172554 | Info/informational states |
|
||||
|
||||
**Standalone** — `tokens/primitives/colours.json`
|
||||
| Token path | Value | Description |
|
||||
|-----------|-------|-------------|
|
||||
| color.white | #FFFFFF | Pure white |
|
||||
| color.black | #000000 | Pure black (use sparingly) |
|
||||
|
||||
### Typography
|
||||
|
||||
`tokens/primitives/typography.json`
|
||||
| Token path | Value | Description |
|
||||
|-----------|-------|-------------|
|
||||
| fontFamily.body | Montserrat, ... | Primary body/UI font |
|
||||
| fontFamily.display | Noto Serif SC, ... | Display/heading serif |
|
||||
| fontFamily.mono | JetBrains Mono, ... | Monospace |
|
||||
| fontSize.xs–4xl | 0.75rem–3rem | Desktop font size scale |
|
||||
| fontSize.mobile.display | 1.75rem | 28px mobile display |
|
||||
| fontSize.mobile.h1 | 1.5rem | 24px mobile H1 |
|
||||
| fontSize.mobile.h2 | 1.25rem | 20px mobile H2 |
|
||||
| fontSize.mobile.h3 | 1.125rem | 18px mobile H3 |
|
||||
| fontWeight.regular–bold | 400–700 | Weight scale |
|
||||
| lineHeight.tight–relaxed | 1.25–1.75 | Leading scale |
|
||||
| letterSpacing.tighter–widest | -0.02em–0.08em | Tracking scale |
|
||||
|
||||
### Spacing
|
||||
|
||||
`tokens/primitives/spacing.json`
|
||||
| Token path | Value | Description |
|
||||
|-----------|-------|-------------|
|
||||
| spacing.0-5–20 | 2px–80px | 4px-based spacing scale |
|
||||
| borderRadius.none–full | 0px–9999px | Radius scale |
|
||||
|
||||
### Effects
|
||||
|
||||
`tokens/primitives/effects.json`
|
||||
| Token path | Value | Description |
|
||||
|-----------|-------|-------------|
|
||||
| shadow.sm–xl | CSS box-shadow strings | Elevation shadows |
|
||||
| opacity.disabled | 0.4 | Disabled elements |
|
||||
| opacity.hover | 0.08 | Hover overlay tint |
|
||||
| opacity.overlay | 0.5 | Modal backdrop |
|
||||
|
||||
## Semantic tokens
|
||||
|
||||
### Colour semantics
|
||||
|
||||
`tokens/semantic/colours.json`
|
||||
| Token path | References | Description |
|
||||
|-----------|-----------|-------------|
|
||||
| color.text.primary | → neutral.800 | Main body/heading text |
|
||||
| color.text.secondary | → neutral.600 | Helper text, descriptions |
|
||||
| color.text.tertiary | → neutral.500 | Placeholders, timestamps |
|
||||
| color.text.disabled | → neutral.400 | Disabled text |
|
||||
| color.text.inverse | → white | Text on dark backgrounds |
|
||||
| color.text.brand | → brand.600 | Links, brand emphasis |
|
||||
| color.text.error | → red.600 | Error messages |
|
||||
| color.text.success | → green.600 | Success messages |
|
||||
| color.text.warning | → amber.700 | Warning messages |
|
||||
| color.surface.default | → white | Main page background |
|
||||
| color.surface.subtle | → neutral.50 | Alternate backgrounds |
|
||||
| color.surface.raised | → white | Cards (with shadow) |
|
||||
| color.surface.warm | → brand.50 | Warm-tinted sections |
|
||||
| color.surface.cool | → sage.50 | Cool/calming sections |
|
||||
| color.surface.overlay | #00000080 | Modal backdrop |
|
||||
| color.border.default | → neutral.200 | Standard borders |
|
||||
| color.border.strong | → neutral.400 | Emphasis borders |
|
||||
| color.border.subtle | → neutral.100 | Soft dividers |
|
||||
| color.border.brand | → brand.500 | Focused inputs, brand borders |
|
||||
| color.border.error | → red.500 | Error field borders |
|
||||
| color.border.success | → green.500 | Success field borders |
|
||||
| color.interactive.default | → brand.500 | Primary button, links |
|
||||
| color.interactive.hover | → brand.600 | Hover state |
|
||||
| color.interactive.active | → brand.700 | Active/pressed state |
|
||||
| color.interactive.disabled | → neutral.300 | Disabled interactive |
|
||||
| color.interactive.focus | → brand.500 | Focus ring colour |
|
||||
| color.interactive.secondary | → sage.700 | Secondary buttons |
|
||||
| color.interactive.secondary-hover | → sage.800 | Secondary hover |
|
||||
| color.feedback.success | → green.600 | Success indicator |
|
||||
| color.feedback.success-subtle | → green.50 | Success background |
|
||||
| color.feedback.warning | → amber.600 | Warning indicator |
|
||||
| color.feedback.warning-subtle | → amber.50 | Warning background |
|
||||
| color.feedback.error | → red.600 | Error indicator |
|
||||
| color.feedback.error-subtle | → red.50 | Error background |
|
||||
| color.feedback.info | → blue.600 | Info indicator |
|
||||
| color.feedback.info-subtle | → blue.50 | Info background |
|
||||
|
||||
### Typography semantics
|
||||
|
||||
`tokens/semantic/typography.json`
|
||||
| Token path | References | Description |
|
||||
|-----------|-----------|-------------|
|
||||
| typography.display.* | fontSize.3xl, fontFamily.display, bold, tight | Hero display text |
|
||||
| typography.h1.* | fontSize.2xl, fontFamily.display, bold, tight | Page headings |
|
||||
| typography.h2.* | fontSize.xl, fontFamily.display, semibold, snug | Section headings |
|
||||
| typography.h3.* | fontSize.lg, fontFamily.body, semibold, snug | Sub-headings |
|
||||
| typography.h4.* | fontSize.md, fontFamily.body, semibold, snug | Minor headings |
|
||||
| typography.bodyLarge.* | fontSize.md, fontFamily.body, regular, relaxed | Lead paragraphs |
|
||||
| typography.body.* | fontSize.base, fontFamily.body, regular, normal | Default body |
|
||||
| typography.bodySmall.* | fontSize.sm, fontFamily.body, regular, normal | Helper text |
|
||||
| typography.caption.* | fontSize.xs, fontFamily.body, regular, snug | Fine print |
|
||||
| typography.label.* | fontSize.sm, fontFamily.body, medium, normal | Form labels |
|
||||
| typography.overline.* | fontSize.xs, fontFamily.body, semibold, snug | Section overlines |
|
||||
|
||||
### Spacing semantics
|
||||
|
||||
`tokens/semantic/spacing.json`
|
||||
| Token path | References | Description |
|
||||
|-----------|-----------|-------------|
|
||||
| spacing.component.xs–lg | → spacing.1–6 | Component internal spacing |
|
||||
| spacing.layout.gutter | → spacing.4 | Grid gutter (mobile) |
|
||||
| spacing.layout.gutter-desktop | → spacing.6 | Grid gutter (desktop) |
|
||||
| spacing.layout.section | → spacing.12 | Page section gap |
|
||||
| spacing.layout.page | → spacing.16 | Major section gap |
|
||||
| spacing.layout.page-padding | → spacing.4 | Page horizontal padding (mobile) |
|
||||
| spacing.layout.page-padding-desktop | → spacing.8 | Page horizontal padding (desktop) |
|
||||
|
||||
## Component tokens
|
||||
|
||||
`tokens/component/button.json`
|
||||
|
||||
### Button — Sizing
|
||||
|
||||
| Token path | Value / Reference | Used by | Description |
|
||||
|-----------|-----------|---------|-------------|
|
||||
| button.height.xs | 28px | Button | Extra-small height — compact text buttons |
|
||||
| button.height.sm | 32px | Button | Small height — secondary actions |
|
||||
| button.height.md | 40px | Button | Medium height — default |
|
||||
| button.height.lg | 48px | Button | Large height — CTAs, mobile (meets 44px touch target) |
|
||||
| button.paddingX.xs–lg | → spacing.2–6 (8–24px) | Button | Horizontal padding per size |
|
||||
| button.paddingY.xs–lg | → spacing.1–3 (4–12px) | Button | Vertical padding per size |
|
||||
| button.fontSize.xs–lg | → fontSize.xs–base (12–16px) | Button | Font size per size |
|
||||
| button.iconSize.xs–lg | 14–20px | Button | Icon dimensions per size |
|
||||
| button.iconGap.xs–lg | → spacing.1–2 (4–8px) | Button | Icon-to-text gap per size |
|
||||
| button.borderRadius.default | → borderRadius.md (8px) | Button | Button corner radius |
|
||||
|
||||
### Card
|
||||
|
||||
`tokens/component/card.json`
|
||||
|
||||
| Token path | Value / Reference | Used by | Description |
|
||||
|-----------|-----------|---------|-------------|
|
||||
| card.borderRadius.default | → borderRadius.md (8px) | Card | Card corner radius |
|
||||
| card.padding.default | → spacing.6 (24px) | Card | Standard card padding (desktop) |
|
||||
| card.padding.compact | → spacing.4 (16px) | Card | Compact card padding (mobile, tight layouts) |
|
||||
| card.shadow.default | → shadow.md | Card | Resting elevation — medium shadow |
|
||||
| card.shadow.hover | → shadow.lg | Card | Hover elevation — interactive cards |
|
||||
| card.border.default | → color.border.default (#E8E8E8) | Card | Outlined card border colour |
|
||||
| card.border.selected | → color.border.brand (#BA834E) | Card | Brand border for selected/active cards |
|
||||
| card.background.default | → color.surface.raised (#FFFFFF) | Card | Card background (raised surface) |
|
||||
| card.background.hover | → color.surface.subtle (#FAFAFA) | Card | Subtle grey fill on hover for interactive cards |
|
||||
| card.background.selected | → color.surface.warm (#FEF9F5) | Card | Warm tint for selected cards |
|
||||
|
||||
### Badge
|
||||
|
||||
`tokens/component/badge.json`
|
||||
|
||||
| Token path | Value / Reference | Used by | Description |
|
||||
|-----------|-----------|---------|-------------|
|
||||
| badge.height.sm | 22px | Badge | Small badge height |
|
||||
| badge.height.md | 26px | Badge | Medium badge height (default) |
|
||||
| badge.paddingX.sm | → spacing.2 (8px) | Badge | Small horizontal padding |
|
||||
| badge.paddingX.md | → spacing.3 (12px) | Badge | Medium horizontal padding |
|
||||
| badge.fontSize.sm | → fontSize.2xs (11px) | Badge | Small badge text |
|
||||
| badge.fontSize.md | → fontSize.xs (12px) | Badge | Medium badge text |
|
||||
| badge.iconSize.sm | 12px | Badge | Small badge icon |
|
||||
| badge.iconSize.md | 14px | Badge | Medium badge icon |
|
||||
| badge.iconGap.default | → spacing.1 (4px) | Badge | Icon-to-text gap |
|
||||
| badge.borderRadius.default | → borderRadius.full (9999px) | Badge | Pill shape |
|
||||
|
||||
### Chip
|
||||
|
||||
`tokens/component/chip.json`
|
||||
|
||||
| Token path | Value / Reference | Used by | Description |
|
||||
|-----------|-----------|---------|-------------|
|
||||
| chip.height.sm | 28px | Chip | Small chip height |
|
||||
| chip.height.md | 32px | Chip | Medium chip height (default) |
|
||||
| chip.paddingX.sm | → spacing.2 (8px) | Chip | Small horizontal padding |
|
||||
| chip.paddingX.md | → spacing.3 (12px) | Chip | Medium horizontal padding |
|
||||
| chip.fontSize.sm | → fontSize.xs (12px) | Chip | Small chip text |
|
||||
| chip.fontSize.md | → fontSize.sm (14px) | Chip | Medium chip text |
|
||||
| chip.iconSize.sm | 16px | Chip | Small chip leading icon |
|
||||
| chip.iconSize.md | 18px | Chip | Medium chip leading icon |
|
||||
| chip.deleteIconSize.sm | 14px | Chip | Small chip delete icon |
|
||||
| chip.deleteIconSize.md | 16px | Chip | Medium chip delete icon |
|
||||
| chip.iconGap.default | → spacing.1 (4px) | Chip | Icon-to-text gap |
|
||||
| chip.borderRadius.default | → borderRadius.full (9999px) | Chip | Pill shape |
|
||||
|
||||
### Switch
|
||||
|
||||
`tokens/component/switch.json`
|
||||
|
||||
| Token path | Value / Reference | Used by | Description |
|
||||
|-----------|-----------|---------|-------------|
|
||||
| switch.track.width | 44px | Switch | Track width |
|
||||
| switch.track.height | 24px | Switch | Track height |
|
||||
| switch.track.borderRadius | → borderRadius.full (9999px) | Switch | Pill shape |
|
||||
| switch.thumb.size | 18px | Switch | Thumb diameter |
|
||||
|
||||
### Radio
|
||||
|
||||
`tokens/component/radio.json`
|
||||
|
||||
| Token path | Value / Reference | Used by | Description |
|
||||
|-----------|-----------|---------|-------------|
|
||||
| radio.size.default | 20px | Radio | Outer circle size |
|
||||
| radio.dotSize.default | 10px | Radio | Inner selected dot size |
|
||||
|
||||
### ProviderCard
|
||||
|
||||
`tokens/component/providerCard.json`
|
||||
|
||||
| Token path | Value / Reference | Used by | Description |
|
||||
|-----------|-----------|---------|-------------|
|
||||
| providerCard.image.height | 180px | ProviderCard | Hero image fixed height |
|
||||
| providerCard.logo.size | 64px | ProviderCard | Logo width/height — rounded rectangle inside image area |
|
||||
| providerCard.logo.borderRadius | → borderRadius.md (8px) | ProviderCard | Rounded rectangle corners |
|
||||
| providerCard.content.padding | → spacing.3 (12px) | ProviderCard | Content area padding |
|
||||
| providerCard.content.gap | → spacing.1 (4px) | ProviderCard | Gap between content rows |
|
||||
|
||||
### VenueCard
|
||||
|
||||
`tokens/component/venueCard.json`
|
||||
|
||||
| Token path | Value / Reference | Used by | Description |
|
||||
|-----------|-----------|---------|-------------|
|
||||
| venueCard.image.height | 180px | VenueCard | Hero image fixed height — matches ProviderCard for list consistency |
|
||||
| venueCard.content.padding | → spacing.3 (12px) | VenueCard | Content area padding |
|
||||
| venueCard.content.gap | → spacing.1 (4px) | VenueCard | Gap between content rows |
|
||||
Reference in New Issue
Block a user