Files
loyalyweb/src/components/for-people/FpCard.tsx

100 lines
3.2 KiB
TypeScript

'use client';
import React from 'react';
/**
* The single card system for the "For People" page.
* Wraps the shared `.fp-card*` classes (defined in VerticalScrollWrapper) so
* every section imports one component and the markup can't drift.
*/
type Theme = 'light' | 'dark' | 'fill';
const themeClass: Record<Theme, string> = {
light: 'fp-card--light',
dark: 'fp-card--dark',
fill: 'fp-card--fill',
};
const DEFAULT_ICON_BG: Record<Theme, string> = {
light: 'rgba(244,190,40,0.14)',
dark: 'rgba(244,190,40,0.14)',
fill: 'rgba(244,190,40,0.16)',
};
const sora = 'Sora, sans-serif';
const GOLD = '#f4be28';
interface TagCardProps {
theme?: Theme;
icon: React.ReactNode;
/** Icon-badge background; falls back to the theme's gold tint. */
iconBg?: string;
/** Icon tint — icons draw in `currentColor`. Falls back to the theme's gold. */
iconColor?: string;
children: React.ReactNode;
className?: string;
style?: React.CSSProperties;
}
/** Compact icon + label pill (radius 12). */
export function FpTagCard({ theme = 'light', icon, iconBg, iconColor, children, className = '', style }: TagCardProps) {
return (
<div className={`fp-card ${themeClass[theme]} ${className}`.trim()} style={style}>
<span className="fp-card-icon" style={{ background: iconBg ?? DEFAULT_ICON_BG[theme], color: iconColor ?? GOLD }}>{icon}</span>
<span style={{
fontSize: 13, fontWeight: 700, fontFamily: sora, letterSpacing: '-0.01em',
whiteSpace: 'nowrap', color: theme === 'light' ? '#171512' : '#fff',
}}>
{children}
</span>
</div>
);
}
interface StatCardProps {
theme?: Theme;
layout?: 'row' | 'column';
icon: React.ReactNode;
iconBg?: string;
/** Icon tint — icons draw in `currentColor`. Falls back to the theme's gold. */
iconColor?: string;
/** May be a plain node or a count-up <span> ref. */
value: React.ReactNode;
label: string;
/** Value text color; defaults to theme-appropriate. */
color?: string;
className?: string;
style?: React.CSSProperties;
}
/** Larger icon + value + label card (radius 20). */
export function FpStatCard({
theme = 'light', layout = 'column', icon, iconBg, iconColor, value, label, color, className = '', style,
}: StatCardProps) {
const dark = theme !== 'light';
const column = layout === 'column';
return (
<div
className={`fp-card fp-card--stat ${themeClass[theme]} ${className}`.trim()}
style={{ flexDirection: column ? 'column' : 'row', alignItems: 'center', ...style }}
>
<span className="fp-card-icon fp-card-icon--lg" style={{ background: iconBg ?? DEFAULT_ICON_BG[theme], color: iconColor ?? GOLD }}>{icon}</span>
<div style={{ textAlign: column ? 'center' : 'left' }}>
<div style={{
fontSize: column ? 'clamp(20px, 2.4vw, 26px)' : 18, fontWeight: 900, fontFamily: sora,
letterSpacing: '-0.03em', lineHeight: 1, color: color ?? (dark ? '#fff' : '#171512'),
}}>
{value}
</div>
<div style={{
fontSize: column ? 11.5 : 10.5, fontWeight: 600, marginTop: 5, fontFamily: sora,
color: dark ? 'rgba(255,255,255,0.55)' : 'rgba(23,21,18,0.5)',
}}>
{label}
</div>
</div>
</div>
);
}