From 811736dbb9acb7deef2c038e2d48b0febac3f9b0 Mon Sep 17 00:00:00 2001 From: Richie Date: Wed, 25 Mar 2026 17:52:01 +1100 Subject: [PATCH] Fix ProviderCard from user feedback + /critique MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User feedback: - "Trusted Partner" → "Verified" badge text - Override Card hover bg fill (grey blended with shadow) — shadow lift only - Logo 48px → 56px, removed white border (shadow only) - Tightened spacing: content padding 16→12px, gap 8→4px, footer py 12→8px /critique findings (27/40 → fixes applied): - P1: Price promoted from footer into content area as bold primary text - P2: Footer simplified to "View packages >" CTA with space-between - Image fallback changed from grey to warm brand.50 - Name truncation relaxed to maxLines={2} for mobile Co-Authored-By: Claude Opus 4.6 (1M context) --- .../molecules/ProviderCard/ProviderCard.tsx | 74 ++++++++++--------- src/theme/generated/tokens.css | 8 +- src/theme/generated/tokens.js | 8 +- tokens/component/providerCard.json | 14 ++-- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/components/molecules/ProviderCard/ProviderCard.tsx b/src/components/molecules/ProviderCard/ProviderCard.tsx index 2ed1c35..ba9bb06 100644 --- a/src/components/molecules/ProviderCard/ProviderCard.tsx +++ b/src/components/molecules/ProviderCard/ProviderCard.tsx @@ -43,7 +43,7 @@ export interface ProviderCardProps { // ─── Constants ─────────────────────────────────────────────────────────────── const LOGO_SIZE = 'var(--fa-provider-card-logo-size)'; -const LOGO_OVERLAP = 24; // half of 48px logo, in px +const LOGO_OVERLAP = 28; // half of 56px logo, in px const IMAGE_HEIGHT = 'var(--fa-provider-card-image-height)'; const CONTENT_PADDING = 'var(--fa-provider-card-content-padding)'; const CONTENT_GAP = 'var(--fa-provider-card-content-gap)'; @@ -60,7 +60,7 @@ const FOOTER_PY = 'var(--fa-provider-card-footer-padding-y)'; * list. Supports verified (paid partner) and unverified (scraped listing) * providers with consistent text alignment for scan readability. * - * **Verified providers** get a hero image, logo overlay, and "Trusted Partner" + * **Verified providers** get a hero image, logo overlay, and "Verified" * badge. **Unverified providers** show text content only — no image, logo, * or verification badge. * @@ -111,7 +111,14 @@ export const ProviderCard = React.forwardRef( padding="none" onClick={onClick} sx={[ - { overflow: 'hidden' }, + { + overflow: 'hidden', + // Override Card's default hover bg fill — shadow lift is enough + // for listing cards. The grey bg fill blends into the shadow. + '&:hover': { + backgroundColor: 'background.paper', + }, + }, ...(Array.isArray(sx) ? sx : [sx]), ]} > @@ -124,10 +131,10 @@ export const ProviderCard = React.forwardRef( backgroundImage: `url(${imageUrl})`, backgroundSize: 'cover', backgroundPosition: 'center', - backgroundColor: 'action.hover', // fallback if image fails + backgroundColor: 'var(--fa-color-brand-50)', // warm fallback if image fails }} > - {/* Trusted Partner badge */} + {/* Verified badge */} ( size="small" icon={} > - Trusted Partner + Verified @@ -154,9 +161,7 @@ export const ProviderCard = React.forwardRef( borderRadius: '50%', objectFit: 'cover', backgroundColor: 'background.paper', - boxShadow: 1, - border: '2px solid', - borderColor: 'background.paper', + boxShadow: '0 2px 8px rgba(0,0,0,0.12)', }} /> )} @@ -175,10 +180,17 @@ export const ProviderCard = React.forwardRef( }} > {/* Provider name */} - + {name} + {/* Price — primary comparison data, prominent position */} + {startingPrice != null && ( + + From ${startingPrice.toLocaleString('en-AU')} + + )} + {/* Meta row: location + reviews */} ( {/* ── Footer bar ── */} - {startingPrice != null && ( - - - Packages from - - - ${startingPrice.toLocaleString('en-AU')} - - - - )} + + + View packages + + + ); }, diff --git a/src/theme/generated/tokens.css b/src/theme/generated/tokens.css index b3bdb1b..1a084d6 100644 --- a/src/theme/generated/tokens.css +++ b/src/theme/generated/tokens.css @@ -27,7 +27,7 @@ --fa-input-height-md: 48px; /** Medium (default) — standard forms, matches Button large for alignment */ --fa-input-icon-size-default: 20px; /** 20px — icon size inside input field, matches Figma trailing icon */ --fa-provider-card-image-height: 180px; /** Fixed image height for consistent card sizing in list layouts */ - --fa-provider-card-logo-size: 48px; /** Logo circle diameter — positioned bottom-left of image, overlapping content area */ + --fa-provider-card-logo-size: 56px; /** Logo circle diameter — positioned bottom-left of image, overlapping content area */ --fa-radio-size-default: 20px; /** Default radio size — matches Figma 16px + padding for 44px touch target area */ --fa-radio-dot-size-default: 10px; /** Selected indicator dot — 50% of outer size */ --fa-switch-track-width: 44px; /** Track width — slightly narrower than Figma 52px for better proportion with 44px touch target */ @@ -269,9 +269,9 @@ --fa-input-gap-default: var(--fa-spacing-2); /** 8px — vertical rhythm between label/input/helper, slightly more generous than Figma's 6px for readability */ --fa-provider-card-footer-background: var(--fa-color-brand-100); /** Warm beige footer — brand.100 provides subtle brand warmth */ --fa-provider-card-footer-padding-x: var(--fa-spacing-4); /** 16px horizontal padding — matches compact card padding */ - --fa-provider-card-footer-padding-y: var(--fa-spacing-3); /** 12px vertical padding — slightly tighter than content area */ - --fa-provider-card-content-padding: var(--fa-spacing-4); /** 16px content padding — compact to maximise text area on listing cards */ - --fa-provider-card-content-gap: var(--fa-spacing-2); /** 8px vertical gap between content rows (name, meta, capability) */ + --fa-provider-card-footer-padding-y: var(--fa-spacing-2); /** 8px vertical padding — compact footer bar */ + --fa-provider-card-content-padding: var(--fa-spacing-3); /** 12px content padding — tight to keep card compact in listing layout */ + --fa-provider-card-content-gap: var(--fa-spacing-1); /** 4px vertical gap between content rows — tight for compact listing cards */ --fa-switch-track-border-radius: var(--fa-border-radius-full); /** Pill shape */ --fa-color-text-primary: var(--fa-color-neutral-800); /** Primary text — body content, headings. Cool charcoal (#2C2E35) for comfortable extended reading */ --fa-color-text-secondary: var(--fa-color-neutral-600); /** Secondary text — helper text, descriptions, metadata, less prominent content */ diff --git a/src/theme/generated/tokens.js b/src/theme/generated/tokens.js index dad18f9..af089aa 100644 --- a/src/theme/generated/tokens.js +++ b/src/theme/generated/tokens.js @@ -73,12 +73,12 @@ export const InputBorderRadiusDefault = "4px"; // 4px — subtle rounding, consi export const InputGapDefault = "8px"; // 8px — vertical rhythm between label/input/helper, slightly more generous than Figma's 6px for readability export const InputIconSizeDefault = "20px"; // 20px — icon size inside input field, matches Figma trailing icon export const ProviderCardImageHeight = "180px"; // Fixed image height for consistent card sizing in list layouts -export const ProviderCardLogoSize = "48px"; // Logo circle diameter — positioned bottom-left of image, overlapping content area +export const ProviderCardLogoSize = "56px"; // Logo circle diameter — positioned bottom-left of image, overlapping content area export const ProviderCardFooterBackground = "#f7ecdf"; // Warm beige footer — brand.100 provides subtle brand warmth export const ProviderCardFooterPaddingX = "16px"; // 16px horizontal padding — matches compact card padding -export const ProviderCardFooterPaddingY = "12px"; // 12px vertical padding — slightly tighter than content area -export const ProviderCardContentPadding = "16px"; // 16px content padding — compact to maximise text area on listing cards -export const ProviderCardContentGap = "8px"; // 8px vertical gap between content rows (name, meta, capability) +export const ProviderCardFooterPaddingY = "8px"; // 8px vertical padding — compact footer bar +export const ProviderCardContentPadding = "12px"; // 12px content padding — tight to keep card compact in listing layout +export const ProviderCardContentGap = "4px"; // 4px vertical gap between content rows — tight for compact listing cards export const RadioSizeDefault = "20px"; // Default radio size — matches Figma 16px + padding for 44px touch target area export const RadioDotSizeDefault = "10px"; // Selected indicator dot — 50% of outer size export const SwitchTrackWidth = "44px"; // Track width — slightly narrower than Figma 52px for better proportion with 44px touch target diff --git a/tokens/component/providerCard.json b/tokens/component/providerCard.json index fb348a7..97ee69a 100644 --- a/tokens/component/providerCard.json +++ b/tokens/component/providerCard.json @@ -9,7 +9,7 @@ "logo": { "$type": "dimension", "$description": "Provider logo overlay dimensions.", - "size": { "$value": "48px", "$description": "Logo circle diameter — positioned bottom-left of image, overlapping content area" } + "size": { "$value": "56px", "$description": "Logo circle diameter — positioned bottom-left of image, overlapping content area" } }, "footer": { "$description": "Footer bar styling — warm beige bar with package pricing.", @@ -25,21 +25,21 @@ }, "paddingY": { "$type": "dimension", - "$value": "{spacing.3}", - "$description": "12px vertical padding — slightly tighter than content area" + "$value": "{spacing.2}", + "$description": "8px vertical padding — compact footer bar" } }, "content": { "$description": "Content area spacing.", "padding": { "$type": "dimension", - "$value": "{spacing.4}", - "$description": "16px content padding — compact to maximise text area on listing cards" + "$value": "{spacing.3}", + "$description": "12px content padding — tight to keep card compact in listing layout" }, "gap": { "$type": "dimension", - "$value": "{spacing.2}", - "$description": "8px vertical gap between content rows (name, meta, capability)" + "$value": "{spacing.1}", + "$description": "4px vertical gap between content rows — tight for compact listing cards" } } }