{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "streak-card",
  "title": "Streak Card",
  "description": "Full streak UI card for React. Daily streak display, longest streak record with optional section for streak rules. Built on shadcn/ui + Tailwind. Open source.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "streak-calendar",
    "button"
  ],
  "files": [
    {
      "path": "registry/trophy/ui/streak-card.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n  CheckCircle2,\n  ChevronDown,\n  ChevronRight,\n  Flame,\n  RefreshCcw,\n} from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  StreakCalendar,\n  type StreakPeriod,\n} from \"@/components/ui/streak-calendar\"\n\ninterface StreakCardProps extends React.HTMLAttributes<HTMLDivElement> {\n  /** Streak periods passed through to StreakCalendar */\n  streak: StreakPeriod[]\n  /** Current streak value in days */\n  currentStreak: number\n  /** Longest streak value in days */\n  longestStreak: number\n  /** Secondary total metric value */\n  total: number\n  /** Optional heading text */\n  title?: string\n  /** Label for the action button */\n  actionLabel?: string\n  /** Callback for action click */\n  onActionClick?: () => void\n  /** Show \"How streaks work\" dropdown section */\n  showHowItWorks?: boolean\n  /** Title for the dropdown trigger */\n  howItWorksTitle?: string\n  /** Content rows shown when the dropdown is expanded */\n  howItWorksItems?: string[]\n  /** Initial expanded state for dropdown */\n  defaultHowItWorksOpen?: boolean\n}\n\nconst StreakCard = React.forwardRef<HTMLDivElement, StreakCardProps>(\n  (\n    {\n      className,\n      streak,\n      currentStreak,\n      longestStreak,\n      total,\n      title = \"Streak\",\n      actionLabel = \"View Details\",\n      onActionClick,\n      showHowItWorks = true,\n      howItWorksTitle = \"How do streaks work?\",\n      howItWorksItems = [\n        \"Complete at least one activity each day to build your streak.\",\n        \"Each day you do an activity, your streak increases.\",\n        \"Missing a day will reset your streak to 0.\",\n      ],\n      defaultHowItWorksOpen = false,\n      ...props\n    },\n    ref\n  ) => {\n    const [isHowItWorksOpen, setIsHowItWorksOpen] = React.useState(\n      defaultHowItWorksOpen\n    )\n    const howItWorksContentId = React.useId()\n\n    return (\n      <section\n        ref={ref}\n        aria-label=\"Streak summary card\"\n        className={cn(\"bg-card rounded-2xl border p-6 shadow-sm\", className)}\n        {...props}\n      >\n        <header className=\"mb-3 flex items-center justify-between gap-3\">\n          <div className=\"flex items-center gap-2\">\n            <Flame className=\"text-primary h-6 w-6\" aria-hidden=\"true\" />\n            <h3 className=\"text-2xl leading-none font-semibold\">{title}</h3>\n          </div>\n          <Button\n            variant=\"link\"\n            size=\"sm\"\n            onClick={onActionClick}\n            aria-label={actionLabel}\n            className=\"text-muted-foreground hover:text-foreground text-sm font-medium transition-colors\"\n          >\n            {actionLabel}\n          </Button>\n        </header>\n\n        <p className=\"mb-4 text-5xl leading-none font-semibold tracking-tight\">\n          {currentStreak}\n          <span className=\"text-muted-foreground ml-2 text-2xl font-medium\">\n            days\n          </span>\n        </p>\n\n        <StreakCalendar\n          streak={streak}\n          view=\"week\"\n          startOfWeek={1}\n          className=\"max-w-none\"\n        />\n\n        <div\n          className=\"mt-4 grid grid-cols-2 gap-4 border-t border-dashed pt-4\"\n          aria-label=\"Streak stats\"\n        >\n          <div>\n            <p className=\"text-muted-foreground text-sm\">Longest Streak</p>\n            <p className=\"text-3xl leading-tight font-semibold\">\n              {longestStreak}\n              <span className=\"ml-1 text-2xl font-medium\">days</span>\n            </p>\n          </div>\n          <div className=\"text-right\">\n            <p className=\"text-muted-foreground text-sm\">Total</p>\n            <p className=\"text-3xl leading-tight font-semibold\">{total}</p>\n          </div>\n        </div>\n\n        {showHowItWorks && (\n          <div className=\"mt-4 border-t pt-4\">\n            <button\n              type=\"button\"\n              className=\"bg-muted flex w-full items-center justify-between rounded-xl px-4 py-3 text-left\"\n              onClick={() => setIsHowItWorksOpen((prev) => !prev)}\n              aria-expanded={isHowItWorksOpen}\n              aria-controls={howItWorksContentId}\n            >\n              <span className=\"text-lg font-semibold\">{howItWorksTitle}</span>\n              <ChevronDown\n                className={cn(\n                  \"text-muted-foreground h-5 w-5 transition-transform\",\n                  isHowItWorksOpen && \"rotate-180\"\n                )}\n                aria-hidden=\"true\"\n              />\n            </button>\n\n            {isHowItWorksOpen && (\n              <div id={howItWorksContentId} className=\"space-y-4 px-2 pt-4\">\n                {howItWorksItems.map((item, index) => {\n                  const Icon =\n                    index === 0\n                      ? CheckCircle2\n                      : index === 1\n                        ? Flame\n                        : RefreshCcw\n                  return (\n                    <div\n                      key={`${item}-${index}`}\n                      className=\"flex items-start gap-3\"\n                    >\n                      <Icon\n                        className=\"text-primary mt-0.5 h-5 w-5 shrink-0\"\n                        aria-hidden=\"true\"\n                      />\n                      <p className=\"text-muted-foreground text-lg leading-snug\">\n                        {item}\n                      </p>\n                    </div>\n                  )\n                })}\n              </div>\n            )}\n          </div>\n        )}\n      </section>\n    )\n  }\n)\nStreakCard.displayName = \"StreakCard\"\n\nexport { StreakCard }\nexport type { StreakCardProps }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}