{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "comingsoon79",
  "title": "Maintenance Window Notice",
  "description": "A scheduled downtime notice with a light heading, a hairline table of what is affected and what is not, two actions, and an image tile floating a live uptime strip.",
  "dependencies": [
    "clsx",
    "tailwind-merge",
    "lucide-react"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "registry/comingsoon79/comingsoon79.tsx",
      "content": "\"use client\";\n\nimport { Badge23 } from \"@/components/beste/component/badge23\";\nimport { Button21 } from \"@/components/beste/component/button21\";\nimport { Indicator14 } from \"@/components/beste/piece/indicator14\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport Link from \"next/link\";\n\ninterface Badge {\n  label: string;\n}\n\ninterface ActionLink {\n  label: string;\n  href: string;\n}\n\ninterface TileImage {\n  src: string;\n  alt: string;\n}\n\ninterface DetailRow {\n  label: string;\n  value: string;\n}\n\ninterface Comingsoon79Props {\n  badge?: Badge;\n  heading?: string;\n  description?: string;\n  details?: DetailRow[];\n  media?: ReactNode;\n  image?: TileImage;\n  buttons?: ActionLink[];\n  contactNote?: string;\n  className?: string;\n}\n\nexport const comingsoon79Demo: Comingsoon79Props = {\n  badge: { label: \"Scheduled maintenance\" },\n  heading: \"Back at 06:00, and bookings are safe in the meantime\",\n  description:\n    \"We are moving the scheduling database onto faster storage. Nothing is being changed, deleted, or migrated between regions while we do it.\",\n  details: [\n    { label: \"Window\", value: \"Sunday 02:00 – 06:00 UK\" },\n    { label: \"Affected\", value: \"Web app and admin only\" },\n    { label: \"Unaffected\", value: \"Member booking links and reminders\" },\n    { label: \"Data\", value: \"Nothing moves outside your region\" },\n  ],\n  media: (\n    <Indicator14\n      title=\"Booking service\"\n      uptime=\"99.98%\"\n      range=\"Last 45 days\"\n      bars={[\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"partial\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"down\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"partial\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n        \"up\",\n      ]}\n    />\n  ),\n  image: {\n    src: \"https://images.unsplash.com/photo-1703593693037-3f816218baa1?q=80&w=2199&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n    alt: \"Deep green gradient backdrop\",\n  },\n  buttons: [\n    { label: \"Follow the status page\", href: \"https://beste.co\" },\n    { label: \"Read the change note\", href: \"https://beste.co\" },\n  ],\n  contactNote:\n    \"If a clinic is opening inside this window, write to us and we will hold the maintenance until you are done.\",\n};\n\nexport function Comingsoon79({\n  badge,\n  heading,\n  description,\n  details = [],\n  media,\n  image,\n  buttons = [],\n  contactNote,\n  className,\n}: Comingsoon79Props) {\n  return (\n    <section className={cn(\"bg-background py-16 md:py-24 w-full\", className)}>\n      <div className=\"mx-auto max-w-7xl px-4 md:px-6\">\n        <div className=\"grid gap-10 lg:grid-cols-2 lg:items-center lg:gap-16\">\n          <div>\n            {badge && <Badge23 label={badge.label} />}\n            {heading && (\n              <h1 className=\"mt-6 text-3xl font-light leading-[1.1] tracking-tight text-foreground md:text-5xl\">\n                {heading}\n              </h1>\n            )}\n            {description && (\n              <p className=\"mt-4 max-w-md text-base leading-relaxed text-muted-foreground md:text-lg\">\n                {description}\n              </p>\n            )}\n\n            {details.length > 0 && (\n              <dl className=\"mt-8\">\n                {details.map((detail, index) => (\n                  <div\n                    key={index}\n                    className=\"flex flex-wrap items-baseline justify-between gap-x-6 gap-y-1 border-t border-border py-3 last:border-b\"\n                  >\n                    <dt className=\"text-sm text-muted-foreground\">{detail.label}</dt>\n                    <dd className=\"text-base text-foreground\">{detail.value}</dd>\n                  </div>\n                ))}\n              </dl>\n            )}\n\n            {buttons.length > 0 && (\n              <div className=\"mt-8 flex flex-wrap items-center gap-3\">\n                {buttons.map((button, index) => (\n                  <Button21\n                    asChild\n                    key={index}\n                    label={button.label}\n                    tone={index === 0 ? \"primary\" : \"outline\"}\n                  >\n                    <Link href={button.href} />\n                  </Button21>\n                ))}\n              </div>\n            )}\n\n            {contactNote && (\n              <p className=\"mt-6 max-w-md text-sm leading-relaxed text-muted-foreground\">\n                {contactNote}\n              </p>\n            )}\n          </div>\n\n          {media && (\n            <div className=\"relative flex h-80 items-center justify-center overflow-hidden rounded-md bg-muted md:h-96\">\n              {image && (\n                <img\n                  className=\"absolute inset-0 size-full object-cover\"\n                  src={image.src}\n                  alt={image.alt}\n                />\n              )}\n              <div className=\"relative z-10 size-full\">{media}</div>\n            </div>\n          )}\n        </div>\n      </div>\n    </section>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/block/comingsoon79.tsx"
    },
    {
      "path": "registry-pieces/indicator14/indicator14.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype Surface = \"card\" | \"glass\";\n\ntype Tone = \"up\" | \"partial\" | \"down\";\n\ninterface Indicator14Props {\n  title?: string;\n  uptime?: string;\n  range?: string;\n  bars?: Tone[];\n  surface?: Surface;\n  bordered?: boolean;\n  inverted?: boolean;\n  className?: string;\n}\n\nconst barStyles: Record<Tone, string> = {\n  up: \"bg-emerald-500\",\n  partial: \"bg-amber-500\",\n  down: \"bg-rose-500\",\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 indicator14Demo: Indicator14Props = {\n  surface: \"card\",\n  bordered: false,\n  inverted: false,\n  title: \"Booking service\",\n  uptime: \"99.98%\",\n  range: \"Last 45 days\",\n  bars: [\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"partial\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"down\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"partial\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n    \"up\",\n  ],\n};\n\nexport function Indicator14({ title, uptime, range, bars = [], surface = \"card\", bordered = false, inverted = false, className }: Indicator14Props) {\n  const surfaceTone = surfaceClasses[surface][inverted ? \"inverted\" : \"plain\"];\n\n  return (\n    <div className={cn(\"relative flex size-full items-center justify-center p-4\", className)}>\n      <div\n        className={cn(\n          \"w-full max-w-80 rounded-md p-5 shadow-xl\",\n          surfaceTone,\n          bordered && \"border border-current/15\"\n        )}\n      >\n        <div className=\"flex items-baseline justify-between gap-3\">\n          {title && (\n            <p className=\"truncate text-sm font-semibold\">{title}</p>\n          )}\n          {uptime && (\n            <span className=\"shrink-0 text-sm font-medium tabular-nums text-emerald-500\">\n              {uptime}\n            </span>\n          )}\n        </div>\n\n        {bars.length > 0 && (\n          <div className=\"mt-3 flex h-8 items-stretch gap-px\" aria-hidden=\"true\">\n            {bars.map((bar, index) => (\n              <span key={index} className={cn(\"flex-1 rounded-sm\", barStyles[bar])} />\n            ))}\n          </div>\n        )}\n\n        {range && <p className=\"mt-2 text-sm text-current/60\">{range}</p>}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/piece/indicator14.tsx"
    },
    {
      "path": "registry-components/badge23/badge23.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype Tone = \"muted\" | \"foreground\" | \"primary\";\n\ninterface Badge23Props {\n  /** Eyebrow label */\n  label: string;\n  /** Text/border tone */\n  tone?: Tone;\n  /** Additional classes merged onto the root */\n  className?: string;\n}\n\nconst toneStyles: Record<Tone, string> = {\n  muted: \"border-border text-muted-foreground\",\n  foreground: \"border-foreground/30 text-foreground\",\n  primary: \"border-primary/40 text-primary\",\n};\n\nexport const badge23Demo: Badge23Props = {\n  label: \"Product\",\n};\n\nexport function Badge23({ label, tone = \"muted\", className }: Badge23Props) {\n  return (\n    <span\n      className={cn(\n        \"inline-flex items-center rounded-md border bg-transparent px-2.5 py-1 text-sm font-medium leading-none\",\n        toneStyles[tone],\n        className\n      )}\n    >\n      {label}\n    </span>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/component/badge23.tsx"
    },
    {
      "path": "registry-components/button21/button21.tsx",
      "content": "\"use client\";\n\nimport type { LucideIcon } from \"lucide-react\";\nimport * as React from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\n\ntype Tone = \"primary\" | \"neutral\" | \"outline\";\n\ninterface Button21Props {\n  /** Button label */\n  label: string;\n  /**\n   * Compose the rendered element shadcn-style (radix asChild): your element\n   * (e.g. a router Link) becomes the root and the button content is injected\n   * as its children. Pass the element without children of its own.\n   */\n  asChild?: boolean;\n  /** The element to render when `asChild` is set (e.g. your framework's Link) */\n  children?: React.ReactElement;\n  /**\n   * Fallback link: renders a plain `<a>`. Prefer `asChild` with your\n   * framework's Link component for client-side navigation.\n   */\n  href?: string;\n  /** Optional trailing icon */\n  icon?: LucideIcon;\n  /** Surface tone: solid accent (default), soft neutral pill, or hairline outline */\n  tone?: Tone;\n  /** Click handler (used when there is no href and no asChild) */\n  onClick?: React.MouseEventHandler<HTMLButtonElement>;\n  /** Additional classes merged onto the button */\n  className?: string;\n}\n\nconst toneStyles: Record<Tone, string> = {\n  primary: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n  neutral: \"bg-muted text-foreground hover:bg-muted/70\",\n  outline: \"border border-border bg-transparent text-foreground hover:bg-muted\",\n};\n\nexport const button21Demo: Button21Props = {\n  label: \"Book a demo\",\n};\n\nexport function Button21({\n  label,\n  asChild = false,\n  children,\n  href,\n  icon: Icon,\n  tone = \"primary\",\n  onClick,\n  className,\n}: Button21Props) {\n  const classes = cn(\n    \"group/button21 h-auto w-fit gap-2 rounded-md px-5 py-2.5 text-sm font-medium tracking-tight transition-colors\",\n    toneStyles[tone],\n    className\n  );\n\n  const inner = (\n    <>\n      {label}\n      {Icon && (\n        <Icon className=\"size-4 transition-transform motion-safe:group-hover/button21:translate-x-0.5\" />\n      )}\n    </>\n  );\n\n  if (asChild && React.isValidElement(children)) {\n    return (\n      <Button asChild className={classes}>\n        {React.cloneElement(children, undefined, inner)}\n      </Button>\n    );\n  }\n\n  if (href) {\n    return (\n      <Button asChild className={classes}>\n        <a href={href}>{inner}</a>\n      </Button>\n    );\n  }\n\n  return (\n    <Button type=\"button\" className={classes} onClick={onClick}>\n      {inner}\n    </Button>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/component/button21.tsx"
    }
  ],
  "type": "registry:block"
}