{
  "name": "subscription-card",
  "title": "SubscriptionCard",
  "description": "Subscription card with billing plan options, trial badge, and setup fee.",
  "type": "component",
  "registryDependencies": [
    "price",
    "cn",
    "strip-html"
  ],
  "files": [
    {
      "path": "cards/subscription-card.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\nimport { stripHtmlToText } from \"@cimplify/sdk/react\";\nimport type { ServiceCardLayoutProps } from \"./standard-service-card\";\nimport { CardShell, CardImage } from \"@cimplify/sdk/react\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { getProductCurrency } from \"@cimplify/sdk\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nconst FREQUENCY_LABELS: Record<string, string> = {\n  weekly: \"/week\",\n  biweekly: \"/2wk\",\n  monthly: \"/mo\",\n  quarterly: \"/qtr\",\n  annually: \"/yr\",\n};\n\nexport function SubscriptionCard({\n  product,\n  onBook,\n  renderImage,\n  renderLink,\n  className,\n}: ServiceCardLayoutProps): React.ReactElement {\n  const image = product.image_url || product.images?.[0] || \"\";\n  const currency = getProductCurrency(product);\n  const plans = product.billing_plans || [];\n  const primaryPlan = plans[0];\n  const frequency = primaryPlan?.frequency\n    ? FREQUENCY_LABELS[primaryPlan.frequency] || `/${primaryPlan.frequency}`\n    : \"/mo\";\n  const hasTrial = primaryPlan?.trial_days != null && primaryPlan.trial_days > 0;\n  const tags = product.tags || [];\n\n  return (\n    <CardShell product={product} renderLink={renderLink} className={className}>\n      <CardImage src={image} alt={product.name} aspectRatio=\"16/9\" renderImage={renderImage}>\n        <div className=\"absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none\" />\n\n        {/* Price on image */}\n        <span className=\"absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm\">\n          <Price amount={product.default_price} currency={currency} />{frequency}\n        </span>\n\n        {/* Trial badge */}\n        {hasTrial && (\n          <span className=\"absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-emerald-50/90 text-emerald-700 border border-emerald-200/50 backdrop-blur px-2 py-0.5 rounded-md\">\n            {primaryPlan!.trial_days}-day free trial\n          </span>\n        )}\n      </CardImage>\n\n      <div className=\"p-4\">\n        <h3 className=\"text-[14.5px] font-bold text-foreground leading-snug tracking-tight\">\n          {product.name}\n        </h3>\n        {product.description && (\n          <p className=\"text-[12.5px] text-muted-foreground mt-1 leading-relaxed line-clamp-2\">\n            {stripHtmlToText(product.description)}\n          </p>\n        )}\n\n        {/* Tags */}\n        {tags.length > 0 && (\n          <div className=\"flex flex-wrap gap-1 mt-2.5\">\n            {tags.slice(0, 3).map((tag) => (\n              <span key={tag} className=\"text-[10px] font-medium text-muted-foreground px-1.5 py-0.5 bg-muted rounded\">\n                {tag}\n              </span>\n            ))}\n          </div>\n        )}\n\n        {/* Billing plan options */}\n        {plans.length > 1 && (\n          <div className=\"mt-3 space-y-1\">\n            {plans.slice(0, 3).map((plan) => {\n              const label = plan.frequency\n                ? plan.frequency.charAt(0).toUpperCase() + plan.frequency.slice(1)\n                : \"Standard\";\n              const hasMarkup = plan.markup_type && plan.markup_amount;\n              const isSavings = plan.markup_type === \"percentage\" && plan.markup_amount != null && plan.markup_amount < 0;\n\n              return (\n                <div key={plan.id} className=\"flex items-center justify-between text-[11px]\">\n                  <span className=\"text-muted-foreground\">{label}</span>\n                  <span className=\"font-medium\">\n                    {hasMarkup && isSavings && (\n                      <span className=\"text-emerald-600 mr-1\">Save {Math.abs(plan.markup_amount!)}%</span>\n                    )}\n                  </span>\n                </div>\n              );\n            })}\n          </div>\n        )}\n\n        <div className=\"flex items-center justify-between mt-3 pt-3 border-t border-border\">\n          <div className=\"flex items-center gap-2 text-[11px] text-muted-foreground\">\n            {hasTrial && (\n              <span className=\"text-emerald-600 font-medium\">Free trial</span>\n            )}\n            {primaryPlan?.setup_fee != null && primaryPlan.setup_fee > 0 && (\n              <span><Price amount={primaryPlan.setup_fee} currency={currency} /> setup</span>\n            )}\n          </div>\n          <button\n            onClick={(e) => { e.preventDefault(); e.stopPropagation(); onBook?.(product); }}\n            className=\"text-[13px] font-semibold text-primary hover:text-primary/80 transition-colors\"\n          >\n            Subscribe &rarr;\n          </button>\n        </div>\n      </div>\n    </CardShell>\n  );\n}\n"
    }
  ]
}
