'use client'; import React, { forwardRef } from 'react'; import { cn, Surface, CheckIcon, CloseIcon, surfaceClasses, useEffectiveSurface, } from '../common'; import { tone as toneTokens, type ToneKey } from '../tokens'; export interface PixelPricingCardProps extends React.HTMLAttributes { tone?: ToneKey; icon?: React.ReactNode; name: string; description?: string; /** Clamp the description to N lines. Defaults to 2; use 'none' to let long copy flow. */ descriptionLines?: 2 | 3 | 'none'; price: { amount: string | number; period?: string; strikethrough?: string | number }; /** Promo badge rendered beside the price (e.g. a discount PixelBadge). */ priceBadge?: React.ReactNode; popular?: { label?: string; tone?: ToneKey }; features?: { label: string; tooltip?: string; included?: boolean; highlight?: boolean }[]; cta?: React.ReactNode; highlight?: boolean; footer?: React.ReactNode; surface?: Surface; /** Render with surface-aware border + radius chrome. Defaults to true — a pricing card needs visible chrome. */ bordered?: boolean; } export const PixelPricingCard = forwardRef( function PixelPricingCard( { tone = 'neutral', icon, name, description, descriptionLines = 2, price, priceBadge, popular, features, cta, highlight = false, footer, surface: surfaceProp, bordered = true, className, ...rest }, ref, ) { const surface = useEffectiveSurface(surfaceProp); const s = surfaceClasses(surface); const t = toneTokens[tone]; const ribbonTone = toneTokens[popular?.tone ?? 'gold']; const Article = 'article' as 'article'; return (
} className={cn( 'relative flex flex-col p-5', bordered && s.border, bordered && s.radiusLg, bordered && (highlight ? t.border : 'border-retro-border'), bordered && (highlight ? t.soft : 'bg-retro-surface/40'), highlight && t.glow, className, )} {...rest} >
{popular && ( {popular.label ?? 'POPULAR'} )}
{icon && ( {icon} )}

{name}

{description ?? ''}

{price.strikethrough !== undefined && ( Previous price {price.strikethrough} )} {price.amount} {price.period && ( {price.period} )} {priceBadge && ( {priceBadge} )}
{features && features.length > 0 && (
    {features.map((f, i) => { const included = f.included !== false; return (
  • {included ? : } {included ? 'Included: ' : 'Not included: '} {f.label}
  • ); })}
)}
{cta &&
{cta}
} {footer && (
{footer}
)}
); }, ); PixelPricingCard.displayName = 'PixelPricingCard';