{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "feature1",
  "title": "Accordion With Live Media",
  "description": "Accordion on the left, swappable media surface on the right. Each row picks its own media kind: image, video, or live registry-component asset.",
  "dependencies": [
    "clsx",
    "tailwind-merge",
    "lucide-react"
  ],
  "registryDependencies": [
    "accordion",
    "badge"
  ],
  "files": [
    {
      "path": "registry/feature1/feature1.tsx",
      "content": "\"use client\";\n\nimport {\n  Accordion,\n  AccordionContent,\n  AccordionItem,\n  AccordionTrigger,\n} from \"@/components/ui/accordion\";\n\nimport { Ai43 } from \"@/components/beste/piece/ai43\";\nimport { Automation1 } from \"@/components/beste/piece/automation1\";\nimport { Automation10 } from \"@/components/beste/piece/automation10\";\nimport { Automation2 } from \"@/components/beste/piece/automation2\";\nimport { Automation8 } from \"@/components/beste/piece/automation8\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { cn } from \"@/lib/utils\";\nimport { useState } from \"react\";\n\ntype ComponentBackground =\n  | { type: \"dots\" }\n  | { type: \"none\" }\n  | { type: \"image\"; src: string; alt?: string }\n  | { type: \"video\"; src: string; alt?: string };\n\ntype FeatureMedia =\n  | { type: \"image\"; src: string; alt?: string }\n  | { type: \"video\"; src: string; alt?: string }\n  | {\n      type: \"component\";\n      component: React.ReactNode;\n      background?: ComponentBackground;\n    };\n\ninterface FeatureItem {\n  title: string;\n  description: string;\n  media: FeatureMedia;\n}\n\ninterface Feature1Props {\n  badge?: {\n    label: string;\n    variant?: \"default\" | \"secondary\" | \"outline\";\n  };\n  heading?: string;\n  description?: string;\n  features?: FeatureItem[];\n  className?: string;\n}\n\nexport const feature1Demo: Feature1Props = {\n  badge: { label: \"Automations\", variant: \"secondary\" },\n  heading: \"Pick a capability, see the surface\",\n  description:\n    \"Open any row to expand its story. The right side updates with the live asset that ships with that capability.\",\n  features: [\n    {\n      title: \"Wire up a single workflow node\",\n      description:\n        \"Drop a trigger or action node onto any canvas. Field labels and values come prebuilt, the app icon picks up your brand mark.\",\n      media: {\n        type: \"component\",\n        component: (\n          <Automation2\n            kind=\"action\"\n            app=\"Gmail\"\n            event=\"Send email\"\n            image=\"https://oud.pics/sm/l/gmail.jpeg\"\n            alt=\"Gmail\"\n            fields={[\n              { label: \"To\", value: \"{{customer.email}}\" },\n              { label: \"Subject\", value: \"Your receipt is ready\" },\n              { label: \"Template\", value: \"receipt-v3\" },\n            ]}\n          />\n        ),\n      },\n    },\n    {\n      title: \"Trigger meets action, in one tile\",\n      description:\n        \"Show the full workflow at a glance. Two apps, two events, an arrow tells the story without an extra paragraph.\",\n      media: {\n        type: \"component\",\n        component: (\n          <Automation1\n            trigger={{\n              src: \"https://oud.pics/sm/l/stripe.jpeg\",\n              alt: \"Stripe\",\n              event: \"Payment received\",\n            }}\n            action={{\n              src: \"https://oud.pics/sm/l/slack.svg\",\n              alt: \"Slack\",\n              event: \"Send #revenue alert\",\n            }}\n          />\n        ),\n      },\n    },\n    {\n      title: \"Hand off the raw model output\",\n      description:\n        \"Download or copy the response as JSON. Useful in debug panels, eval reports, and tool-call documentation.\",\n      media: {\n        type: \"component\",\n        component: (\n          <Ai43\n            filename=\"response.json\"\n            content={`{\n  \"answer\": \"Use Redis INCR\",\n  \"sources\": 3,\n  \"latency_ms\": 420\n}`}\n          />\n        ),\n      },\n    },\n    {\n      title: \"Toggle automations live\",\n      description:\n        \"An on/off card with run counts and a brand-aware tone. Drop it into dashboards so the team sees what's running without opening the editor.\",\n      media: {\n        type: \"component\",\n        component: (\n          <Automation8\n            name=\"Stripe → Slack revenue alerts\"\n            description=\"Posts a message in #revenue when a payment over $500 lands.\"\n            image=\"https://oud.pics/sm/l/stripe.jpeg\"\n            alt=\"Stripe\"\n            active\n            runsToday={28}\n            tone=\"emerald\"\n          />\n        ),\n      },\n    },\n    {\n      title: \"Package recipes for installs\",\n      description:\n        \"Pre-built workflow recipes with a multi-app stack and an install count. Perfect for an integrations marketplace.\",\n      media: {\n        type: \"component\",\n        component: (\n          <Automation10\n            apps={[\n              { image: \"https://oud.pics/sm/l/stripe.jpeg\", alt: \"Stripe\" },\n              { image: \"https://oud.pics/sm/l/notion.png\", alt: \"Notion\" },\n              { image: \"https://oud.pics/sm/l/slack.svg\", alt: \"Slack\" },\n            ]}\n            name=\"Sync paid invoices to Notion and ping Slack\"\n            description=\"Triggers on Stripe payment, logs the invoice in Notion, and posts a thread to #revenue.\"\n            installs={4280}\n            tone=\"primary\"\n          />\n        ),\n      },\n    },\n  ],\n};\n\nexport function Feature1({ badge, heading, description, features = [], className }: Feature1Props) {\n  const [activeIndex, setActiveIndex] = useState(0);\n  const activeMedia = features[activeIndex]?.media;\n\n  return (\n    <section className={cn(\"py-16 md:py-24 w-full\", className)}>\n      <div className=\"mx-auto max-w-6xl px-4 md:px-6\">\n        {(badge || heading || description) && (\n          <div className=\"mx-auto mb-12 max-w-3xl text-center\">\n            {badge && (\n              <div className=\"mb-4 flex justify-center\">\n                <Badge variant={badge.variant ?? \"default\"}>{badge.label}</Badge>\n              </div>\n            )}\n            {heading && <h2 className=\"text-2xl font-semibold md:text-4xl\">{heading}</h2>}\n            {description && (\n              <p className=\"mt-4 text-base md:text-lg text-muted-foreground\">{description}</p>\n            )}\n          </div>\n        )}\n\n        <div className=\"grid items-start gap-8 md:grid-cols-2 md:gap-12\">\n          <Accordion\n            type=\"single\"\n            collapsible\n            defaultValue=\"item-0\"\n            onValueChange={(value) => {\n              if (!value) return;\n              const next = Number(value.replace(\"item-\", \"\"));\n              if (!Number.isNaN(next)) setActiveIndex(next);\n            }}\n          >\n            {features.map((feature, index) => (\n              <AccordionItem key={index} value={`item-${index}`}>\n                <AccordionTrigger className=\"text-left text-base font-medium md:text-lg\">\n                  {feature.title}\n                </AccordionTrigger>\n                <AccordionContent>\n                  <p className=\"text-sm text-muted-foreground md:text-base\">\n                    {feature.description}\n                  </p>\n                  <div className=\"mt-4 md:hidden\">\n                    <FeatureMediaSurface media={feature.media} />\n                  </div>\n                </AccordionContent>\n              </AccordionItem>\n            ))}\n          </Accordion>\n\n          <div className=\"hidden md:block\">\n            {activeMedia && <FeatureMediaSurface media={activeMedia} />}\n          </div>\n        </div>\n      </div>\n    </section>\n  );\n}\n\nfunction FeatureMediaSurface({ media }: { media: FeatureMedia }) {\n  const componentBackground =\n    media.type === \"component\" ? (media.background ?? { type: \"dots\" }) : null;\n  const showDots = componentBackground?.type === \"dots\";\n\n  return (\n    <div\n      className=\"relative flex aspect-[4/3] items-center justify-center overflow-hidden rounded-md border bg-muted/30\"\n      style={\n        showDots\n          ? {\n              backgroundImage: \"radial-gradient(circle, var(--border) 1px, transparent 1px)\",\n              backgroundSize: \"16px 16px\",\n            }\n          : undefined\n      }\n    >\n      {componentBackground?.type === \"image\" && (\n        <img\n          className=\"absolute inset-0 size-full object-cover\"\n          src={componentBackground.src}\n          alt={componentBackground.alt ?? \"\"}\n          aria-hidden=\"true\"\n        />\n      )}\n      {componentBackground?.type === \"video\" && (\n        <video\n          src={componentBackground.src}\n          autoPlay\n          loop\n          muted\n          playsInline\n          className=\"absolute inset-0 size-full object-cover\"\n        />\n      )}\n\n      {media.type === \"video\" ? (\n        <video\n          src={media.src}\n          autoPlay\n          loop\n          muted\n          playsInline\n          aria-label={media.alt}\n          className=\"size-full object-cover\"\n        />\n      ) : media.type === \"image\" ? (\n        <img\n          className=\"absolute inset-0 size-full object-cover\"\n          src={media.src}\n          alt={media.alt ?? \"\"}\n        />\n      ) : (\n        <div className=\"relative flex size-full items-center justify-center\">{media.component}</div>\n      )}\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/block/feature1.tsx"
    },
    {
      "path": "registry-pieces/ai43/ai43.tsx",
      "content": "\"use client\";\n\nimport { Braces, Copy } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\ninterface Ai43Props {\n  content?: string;\n  filename?: string;\n  className?: string;\n}\n\nexport const ai43Demo: Ai43Props = {\n  filename: \"response.json\",\n  content: `{\n  \"answer\": \"Use Redis INCR\",\n  \"sources\": 3,\n  \"latency_ms\": 420\n}`,\n};\n\nexport function Ai43({\n  filename = \"response.json\",\n  content = \"{}\",\n  className,\n}: Ai43Props) {\n  return (\n    <div\n      className={cn(\n        \"relative flex size-full items-center justify-center p-4\",\n        className\n      )}\n    >\n      <div className=\"flex w-full max-w-80 flex-col overflow-hidden rounded-md border border-border bg-card shadow-sm\">\n        <div className=\"flex items-center justify-between gap-2 border-b border-border px-3 py-1.5\">\n          <div className=\"flex items-center gap-1.5\">\n            <Braces\n              className=\"size-3 text-muted-foreground\"\n              aria-hidden=\"true\"\n            />\n            <span className=\"font-mono text-xs text-card-foreground\">\n              {filename}\n            </span>\n          </div>\n          <button\n            type=\"button\"\n            className=\"inline-flex items-center gap-1 rounded-sm px-1.5 py-0.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground\"\n            aria-label=\"Copy\"\n          >\n            <Copy className=\"size-3\" />\n          </button>\n        </div>\n        <pre className=\"max-h-28 overflow-hidden whitespace-pre px-3 py-2 font-mono text-xs leading-relaxed text-card-foreground\">\n          {content}\n        </pre>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/piece/ai43.tsx"
    },
    {
      "path": "registry-pieces/automation1/automation1.tsx",
      "content": "\"use client\";\nimport type { LucideIcon } from \"lucide-react\";\nimport {\n  ArrowDown,\n  Calendar,\n  CreditCard,\n  FileText,\n  GitBranch,\n  Hash,\n  Mail,\n  MessageSquare,\n} from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\ntype Surface = \"card\" | \"glass\";\n\ntype AppPreset =\n  | \"slack\"\n  | \"gmail\"\n  | \"stripe\"\n  | \"calendar\"\n  | \"github\"\n  | \"notion\"\n  | \"discord\";\n\ninterface Automation1Step {\n  preset?: AppPreset;\n  src?: string;\n  alt?: string;\n  event: string;\n}\n\ninterface Automation1Props {\n  trigger?: Automation1Step;\n  action?: Automation1Step;\n  triggerLabel?: string;\n  actionLabel?: string;\n  surface?: Surface;\n  bordered?: boolean;\n  inverted?: boolean;\n  className?: string;\n}\n\nconst APPS: Record<\n  AppPreset,\n  { label: string; icon: LucideIcon; tile: string }\n> = {\n  slack: { label: \"Slack\", icon: Hash, tile: \"bg-violet-500 text-white\" },\n  gmail: { label: \"Gmail\", icon: Mail, tile: \"bg-rose-500 text-white\" },\n  stripe: {\n    label: \"Stripe\",\n    icon: CreditCard,\n    tile: \"bg-indigo-500 text-white\",\n  },\n  calendar: {\n    label: \"Calendar\",\n    icon: Calendar,\n    tile: \"bg-sky-500 text-white\",\n  },\n  github: {\n    label: \"GitHub\",\n    icon: GitBranch,\n    tile: \"bg-neutral-900 text-white dark:bg-neutral-100 dark:text-neutral-900\",\n  },\n  notion: {\n    label: \"Notion\",\n    icon: FileText,\n    tile: \"bg-neutral-900 text-white dark:bg-neutral-100 dark:text-neutral-900\",\n  },\n  discord: {\n    label: \"Discord\",\n    icon: MessageSquare,\n    tile: \"bg-indigo-600 text-white\",\n  },\n};\n\n\n/* The card sets the colour and everything inside it is drawn in `current`, so\n   inverting is two classes rather than a condition on every element.\n   `glass` is a deliberate exception to the solid-surface rule: these pieces sit\n   over section background images, and a frosted panel is the point of it. */\nconst surfaceClasses: Record<Surface, { plain: string; inverted: string }> = {\n  card: {\n    plain: \"bg-card text-card-foreground\",\n    inverted: \"bg-foreground text-background\",\n  },\n  glass: {\n    plain: \"bg-card/60 text-card-foreground backdrop-blur-md\",\n    inverted: \"bg-foreground/60 text-background backdrop-blur-md\",\n  },\n};\n\nexport const automation1Demo: Automation1Props = {\n  surface: \"card\",\n  bordered: true,\n  inverted: false,\n  triggerLabel: \"When\",\n  actionLabel: \"Then\",\n  trigger: {\n    src: \"https://oud.pics/sm/l/stripe.jpeg\",\n    alt: \"Stripe\",\n    event: \"Payment received\",\n  },\n  action: {\n    src: \"https://oud.pics/sm/l/slack.svg\",\n    alt: \"Slack\",\n    event: \"Send #revenue alert\",\n  },\n};\n\nfunction Tile({ step }: { step: Automation1Step }) {\n  if (step.src) {\n    return (\n      <span className=\"relative size-9 shrink-0 overflow-hidden rounded-md bg-current/10\">\n        <img\n          src={step.src}\n          alt={step.alt ?? \"\"}\n          className=\"absolute inset-0 size-full object-cover\"\n        />\n      </span>\n    );\n  }\n  if (step.preset) {\n    const cfg = APPS[step.preset];\n    const Icon = cfg.icon;\n    return (\n      <span\n        className={cn(\n          \"flex size-9 shrink-0 items-center justify-center rounded-md\",\n          cfg.tile\n        )}\n        aria-hidden=\"true\"\n      >\n        <Icon className=\"size-4\" />\n      </span>\n    );\n  }\n  return <span className=\"size-9 shrink-0 rounded-md bg-current/10\" aria-hidden=\"true\" />;\n}\n\nfunction labelFor(step: Automation1Step) {\n  if (step.alt) return step.alt;\n  if (step.preset) return APPS[step.preset].label;\n  return \"App\";\n}\n\nfunction Row({ kind, step }: { kind: string; step: Automation1Step }) {\n  return (\n    <div className=\"flex items-center gap-2 rounded-md border border-current/15 p-2\">\n      <Tile step={step} />\n      <div className=\"flex min-w-0 flex-1 flex-col\">\n        <div className=\"flex items-baseline gap-1.5\">\n          <span className=\"text-xs font-semibold uppercase tracking-wide text-current/60\">\n            {kind}\n          </span>\n          <span className=\"truncate text-xs font-semibold\">\n            {labelFor(step)}\n          </span>\n        </div>\n        <span className=\"truncate text-xs text-current/60\">\n          {step.event}\n        </span>\n      </div>\n    </div>\n  );\n}\n\nexport function Automation1({\n  trigger = { preset: \"slack\", event: \"Trigger event\" },\n  action = { preset: \"gmail\", event: \"Action event\" },\n  triggerLabel = \"When\",\n  actionLabel = \"Then\",\n  surface = \"card\",\n  bordered = true,\n  inverted = false,\n  className,\n}: Automation1Props) {\n  const surfaceTone = surfaceClasses[surface][inverted ? \"inverted\" : \"plain\"];\n\n  return (\n    <div\n      className={cn(\n        \"relative flex size-full items-center justify-center p-4\",\n        className\n      )}\n    >\n      <div className={cn(\"flex w-full max-w-80 flex-col gap-1 rounded-md p-3 shadow-sm\", surfaceTone, bordered && \"border border-current/15\")}>\n        <Row kind={triggerLabel} step={trigger} />\n        <div className=\"flex items-center justify-center py-0.5\">\n          <span\n            className=\"flex size-5 items-center justify-center rounded-full border border-current/15 bg-current/10\"\n            aria-hidden=\"true\"\n          >\n            <ArrowDown className=\"size-3 text-current/60\" />\n          </span>\n        </div>\n        <Row kind={actionLabel} step={action} />\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/piece/automation1.tsx"
    },
    {
      "path": "registry-pieces/automation10/automation10.tsx",
      "content": "\"use client\";\nimport type { LucideIcon } from \"lucide-react\";\nimport {\n  ArrowRight,\n  CreditCard,\n  FileText,\n  Hash,\n  Mail,\n  MessageSquare,\n  Plus,\n} from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\ntype Surface = \"card\" | \"glass\";\n\ntype Tone =\n  | \"primary\"\n  | \"foreground\"\n  | \"violet\"\n  | \"emerald\"\n  | \"sky\"\n  | \"amber\";\n\ntype AppPreset = \"slack\" | \"gmail\" | \"stripe\" | \"notion\" | \"discord\";\n\ninterface AppItem {\n  preset?: AppPreset;\n  image?: string;\n  alt?: string;\n}\n\ninterface Automation10Props {\n  apps?: AppItem[];\n  name?: string;\n  description?: string;\n  installs?: number;\n  installsLabel?: string;\n  ctaLabel?: string;\n  tone?: Tone;\n  surface?: Surface;\n  bordered?: boolean;\n  inverted?: boolean;\n  className?: string;\n}\n\nconst PRESETS: Record<AppPreset, { icon: LucideIcon; tile: string }> = {\n  slack: { icon: Hash, tile: \"bg-violet-500 text-white\" },\n  gmail: { icon: Mail, tile: \"bg-rose-500 text-white\" },\n  stripe: { icon: CreditCard, tile: \"bg-indigo-500 text-white\" },\n  notion: {\n    icon: FileText,\n    tile: \"bg-neutral-900 text-white dark:bg-neutral-100 dark:text-neutral-900\",\n  },\n  discord: { icon: MessageSquare, tile: \"bg-indigo-600 text-white\" },\n};\n\nconst ctaClasses: Record<Tone, string> = {\n  primary: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n  foreground: \"bg-foreground text-background hover:bg-current/90\",\n  violet: \"bg-violet-500 text-white hover:bg-violet-600\",\n  emerald: \"bg-emerald-500 text-white hover:bg-emerald-600\",\n  sky: \"bg-sky-500 text-white hover:bg-sky-600\",\n  amber: \"bg-amber-500 text-white hover:bg-amber-600\",\n};\n\n\n/* The card sets the colour and everything inside it is drawn in `current`, so\n   inverting is two classes rather than a condition on every element.\n   `glass` is a deliberate exception to the solid-surface rule: these pieces sit\n   over section background images, and a frosted panel is the point of it. */\nconst surfaceClasses: Record<Surface, { plain: string; inverted: string }> = {\n  card: {\n    plain: \"bg-card text-card-foreground\",\n    inverted: \"bg-foreground text-background\",\n  },\n  glass: {\n    plain: \"bg-card/60 text-card-foreground backdrop-blur-md\",\n    inverted: \"bg-foreground/60 text-background backdrop-blur-md\",\n  },\n};\n\nexport const automation10Demo: Automation10Props = {\n  surface: \"card\",\n  bordered: true,\n  inverted: false,\n  apps: [\n    { image: \"https://oud.pics/sm/l/stripe.jpeg\", alt: \"Stripe\" },\n    { image: \"https://oud.pics/sm/l/notion.png\", alt: \"Notion\" },\n    { image: \"https://oud.pics/sm/l/slack.svg\", alt: \"Slack\" },\n  ],\n  name: \"Sync paid invoices to Notion and ping Slack\",\n  description:\n    \"Triggers on Stripe payment, logs the invoice in Notion, and posts a thread to #revenue.\",\n  installs: 4280,\n  installsLabel: \"installs\",\n  ctaLabel: \"Use recipe\",\n  tone: \"primary\",\n};\n\nfunction AppIcon({ item }: { item: AppItem }) {\n  if (item.image) {\n    return (\n      <span className=\"relative size-7 shrink-0 overflow-hidden rounded-md bg-current/10\">\n        <img\n          src={item.image}\n          alt={item.alt ?? \"\"}\n          className=\"absolute inset-0 size-full object-cover\"\n        />\n      </span>\n    );\n  }\n  if (item.preset) {\n    const cfg = PRESETS[item.preset];\n    const Icon = cfg.icon;\n    return (\n      <span\n        className={cn(\n          \"flex size-7 shrink-0 items-center justify-center rounded-md\",\n          cfg.tile\n        )}\n        aria-hidden=\"true\"\n      >\n        <Icon className=\"size-3.5\" />\n      </span>\n    );\n  }\n  return (\n    <span\n      className=\"size-7 shrink-0 rounded-md bg-current/10\"\n      aria-hidden=\"true\"\n    />\n  );\n}\n\nexport function Automation10({\n  apps = [],\n  name = \"Recipe\",\n  description,\n  installs,\n  installsLabel = \"installs\",\n  ctaLabel = \"Use recipe\",\n  tone = \"primary\",\n  surface = \"card\",\n  bordered = true,\n  inverted = false,\n  className,\n}: Automation10Props) {\n  const surfaceTone = surfaceClasses[surface][inverted ? \"inverted\" : \"plain\"];\n\n  return (\n    <div\n      className={cn(\n        \"relative flex size-full items-center justify-center p-4\",\n        className\n      )}\n    >\n      <div className={cn(\"flex w-full max-w-80 flex-col gap-2 rounded-md p-3 shadow-sm\", surfaceTone, bordered && \"border border-current/15\")}>\n        <div className=\"flex items-center gap-1\">\n          {apps.map((a, i) => (\n            <div key={i} className=\"flex items-center gap-1\">\n              <AppIcon item={a} />\n              {i < apps.length - 1 && (\n                <ArrowRight\n                  className=\"size-3 text-current/60\"\n                  aria-hidden=\"true\"\n                />\n              )}\n            </div>\n          ))}\n        </div>\n        <span className=\"text-sm font-semibold\">\n          {name}\n        </span>\n        {description && (\n          <p className=\"line-clamp-2 text-xs leading-snug text-current/60\">\n            {description}\n          </p>\n        )}\n        <div className=\"flex items-center justify-between border-t border-current/15 pt-2\">\n          {typeof installs === \"number\" && (\n            <span className=\"font-mono text-xs tabular-nums text-current/60\">\n              {installs.toLocaleString()} {installsLabel}\n            </span>\n          )}\n          <button\n            type=\"button\"\n            className={cn(\n              \"ml-auto inline-flex items-center gap-1 rounded-sm px-2.5 py-1 text-xs font-semibold transition-colors\",\n              ctaClasses[tone]\n            )}\n          >\n            <Plus className=\"size-3\" aria-hidden=\"true\" />\n            {ctaLabel}\n          </button>\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/piece/automation10.tsx"
    },
    {
      "path": "registry-pieces/automation2/automation2.tsx",
      "content": "\"use client\";\nimport { ChevronDown, Mail, MoreVertical } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\ntype Surface = \"card\" | \"glass\";\n\ninterface Automation2Field {\n  label: string;\n  value: string;\n}\n\ninterface Automation2Props {\n  kind?: string;\n  app?: string;\n  event?: string;\n  image?: string;\n  alt?: string;\n  fields?: Automation2Field[];\n  configureLabel?: string;\n  surface?: Surface;\n  bordered?: boolean;\n  inverted?: boolean;\n  className?: string;\n}\n\n\n/* The card sets the colour and everything inside it is drawn in `current`, so\n   inverting is two classes rather than a condition on every element.\n   `glass` is a deliberate exception to the solid-surface rule: these pieces sit\n   over section background images, and a frosted panel is the point of it. */\nconst surfaceClasses: Record<Surface, { plain: string; inverted: string }> = {\n  card: {\n    plain: \"bg-card text-card-foreground\",\n    inverted: \"bg-foreground text-background\",\n  },\n  glass: {\n    plain: \"bg-card/60 text-card-foreground backdrop-blur-md\",\n    inverted: \"bg-foreground/60 text-background backdrop-blur-md\",\n  },\n};\n\nexport const automation2Demo: Automation2Props = {\n  surface: \"card\",\n  bordered: true,\n  inverted: false,\n  kind: \"Action\",\n  app: \"Gmail\",\n  event: \"Send email\",\n  image: \"https://oud.pics/sm/l/gmail.jpeg\",\n  alt: \"Gmail\",\n  configureLabel: \"Configure\",\n  fields: [\n    { label: \"To\", value: \"{{customer.email}}\" },\n    { label: \"Subject\", value: \"Your receipt is ready\" },\n    { label: \"Template\", value: \"receipt-v3\" },\n  ],\n};\n\nexport function Automation2({\n  kind = \"Step\",\n  app = \"App\",\n  event = \"Event\",\n  image,\n  alt,\n  fields = [],\n  configureLabel = \"Configure\",\n  surface = \"card\",\n  bordered = true,\n  inverted = false,\n  className,\n}: Automation2Props) {\n  const surfaceTone = surfaceClasses[surface][inverted ? \"inverted\" : \"plain\"];\n\n  return (\n    <div\n      className={cn(\n        \"relative flex size-full items-center justify-center p-4\",\n        className\n      )}\n    >\n      <div className={cn(\"flex w-full max-w-80 flex-col overflow-hidden rounded-md shadow-sm\", surfaceTone, bordered && \"border border-current/15\")}>\n        <div className=\"flex items-center gap-2 border-b border-current/15 px-3 py-2\">\n          {image ? (\n            <span className=\"relative size-7 shrink-0 overflow-hidden rounded-md bg-current/10\">\n              <img\n                src={image}\n                alt={alt ?? app}\n                className=\"absolute inset-0 size-full object-cover\"\n              />\n            </span>\n          ) : (\n            <span\n              className=\"flex size-7 shrink-0 items-center justify-center rounded-md bg-muted-foreground text-background\"\n              aria-hidden=\"true\"\n            >\n              <Mail className=\"size-3.5\" />\n            </span>\n          )}\n          <div className=\"flex min-w-0 flex-1 flex-col\">\n            <span className=\"text-xs font-semibold uppercase tracking-wide text-current/60\">\n              {kind}\n            </span>\n            <span className=\"truncate text-sm font-semibold\">\n              {app} · {event}\n            </span>\n          </div>\n          <button\n            type=\"button\"\n            className=\"text-current/60 hover:text-foreground\"\n            aria-label=\"More\"\n          >\n            <MoreVertical className=\"size-4\" />\n          </button>\n        </div>\n        <div className=\"flex flex-col\">\n          {fields.map((f, i) => (\n            <div\n              key={i}\n              className=\"flex items-center justify-between gap-2 border-t border-current/15 px-3 py-1.5 first:border-t-0\"\n            >\n              <span className=\"text-xs text-current/60\">{f.label}</span>\n              <span className=\"truncate font-mono text-xs\">\n                {f.value}\n              </span>\n            </div>\n          ))}\n          <div className=\"flex items-center justify-center gap-1 border-t border-current/15 bg-current/5 py-1.5 text-xs text-current/60\">\n            <ChevronDown className=\"size-3\" aria-hidden=\"true\" />\n            <span>{configureLabel}</span>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/piece/automation2.tsx"
    },
    {
      "path": "registry-pieces/automation8/automation8.tsx",
      "content": "\"use client\";\nimport { Zap } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\ntype Surface = \"card\" | \"glass\";\n\ntype Tone =\n  | \"primary\"\n  | \"foreground\"\n  | \"violet\"\n  | \"emerald\"\n  | \"sky\"\n  | \"amber\";\n\ninterface Automation8Props {\n  name?: string;\n  description?: string;\n  image?: string;\n  alt?: string;\n  active?: boolean;\n  runsToday?: number;\n  activeLabel?: string;\n  pausedLabel?: string;\n  runsLabel?: string;\n  tone?: Tone;\n  surface?: Surface;\n  bordered?: boolean;\n  inverted?: boolean;\n  className?: string;\n}\n\nconst switchOnClasses: Record<Tone, string> = {\n  primary: \"bg-primary\",\n  foreground: \"bg-foreground\",\n  violet: \"bg-violet-500\",\n  emerald: \"bg-emerald-500\",\n  sky: \"bg-sky-500\",\n  amber: \"bg-amber-500\",\n};\n\nconst switchTextOn: Record<Tone, string> = {\n  primary: \"text-primary\",\n  foreground: \"text-foreground\",\n  violet: \"text-violet-600 dark:text-violet-400\",\n  emerald: \"text-emerald-600 dark:text-emerald-400\",\n  sky: \"text-sky-600 dark:text-sky-400\",\n  amber: \"text-amber-600 dark:text-amber-400\",\n};\n\n\n/* The card sets the colour and everything inside it is drawn in `current`, so\n   inverting is two classes rather than a condition on every element.\n   `glass` is a deliberate exception to the solid-surface rule: these pieces sit\n   over section background images, and a frosted panel is the point of it. */\nconst surfaceClasses: Record<Surface, { plain: string; inverted: string }> = {\n  card: {\n    plain: \"bg-card text-card-foreground\",\n    inverted: \"bg-foreground text-background\",\n  },\n  glass: {\n    plain: \"bg-card/60 text-card-foreground backdrop-blur-md\",\n    inverted: \"bg-foreground/60 text-background backdrop-blur-md\",\n  },\n};\n\nexport const automation8Demo: Automation8Props = {\n  surface: \"card\",\n  bordered: true,\n  inverted: false,\n  name: \"Stripe → Slack revenue alerts\",\n  description: \"Posts a message in #revenue when a payment over $500 lands.\",\n  image: \"https://oud.pics/sm/l/stripe.jpeg\",\n  alt: \"Stripe\",\n  active: true,\n  runsToday: 28,\n  activeLabel: \"Active\",\n  pausedLabel: \"Paused\",\n  runsLabel: \"runs today\",\n  tone: \"emerald\",\n};\n\nexport function Automation8({\n  name = \"Workflow\",\n  description,\n  image,\n  alt,\n  active = false,\n  runsToday,\n  activeLabel = \"Active\",\n  pausedLabel = \"Paused\",\n  runsLabel = \"runs today\",\n  tone = \"emerald\",\n  surface = \"card\",\n  bordered = true,\n  inverted = false,\n  className,\n}: Automation8Props) {\n  const surfaceTone = surfaceClasses[surface][inverted ? \"inverted\" : \"plain\"];\n\n  return (\n    <div\n      className={cn(\n        \"relative flex size-full items-center justify-center p-4\",\n        className\n      )}\n    >\n      <div className={cn(\"flex w-full max-w-80 items-start gap-2.5 rounded-md p-3 shadow-sm\", surfaceTone, bordered && \"border border-current/15\")}>\n        {image ? (\n          <span className=\"relative size-8 shrink-0 overflow-hidden rounded-md bg-current/10\">\n            <img\n              src={image}\n              alt={alt ?? name}\n              className=\"absolute inset-0 size-full object-cover\"\n            />\n          </span>\n        ) : (\n          <span\n            className=\"flex size-8 shrink-0 items-center justify-center rounded-md bg-amber-500/15 text-amber-600 dark:text-amber-400\"\n            aria-hidden=\"true\"\n          >\n            <Zap className=\"size-4\" />\n          </span>\n        )}\n        <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n          <div className=\"flex items-center justify-between gap-2\">\n            <span className=\"truncate text-xs font-semibold\">\n              {name}\n            </span>\n            <button\n              type=\"button\"\n              role=\"switch\"\n              aria-checked={active}\n              className={cn(\n                \"relative inline-flex h-4 w-7 shrink-0 items-center rounded-full transition-colors\",\n                active ? switchOnClasses[tone] : \"bg-current/10\"\n              )}\n            >\n              <span\n                className={cn(\n                  \"inline-block size-3 rounded-full bg-white shadow transition-transform\",\n                  active ? \"translate-x-3.5\" : \"translate-x-0.5\"\n                )}\n                aria-hidden=\"true\"\n              />\n            </button>\n          </div>\n          {description && (\n            <p className=\"line-clamp-2 text-xs leading-snug text-current/60\">\n              {description}\n            </p>\n          )}\n          <div className=\"flex items-center justify-between pt-1 text-xs\">\n            <span\n              className={cn(\n                \"font-medium\",\n                active ? switchTextOn[tone] : \"text-current/60\"\n              )}\n            >\n              {active ? activeLabel : pausedLabel}\n            </span>\n            {typeof runsToday === \"number\" && (\n              <span className=\"font-mono tabular-nums text-current/60\">\n                {runsToday} {runsLabel}\n              </span>\n            )}\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/piece/automation8.tsx"
    }
  ],
  "type": "registry:block"
}