{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "badge",
  "title": "Badge",
  "description": "Badge from the Get IT Done design system.",
  "dependencies": [
    "class-variance-authority@^0.7.0"
  ],
  "registryDependencies": [
    "https://zero-design.itdone.de/r/labels-context.json",
    "https://zero-design.itdone.de/r/utils.json",
    "https://zero-design.itdone.de/r/theme.json"
  ],
  "files": [
    {
      "path": "registry/ui/badge.tsx",
      "content": "'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from '@/lib/utils';\nimport { usePreset } from '@/components/ui/labels-context';\n\nconst badgeVariants = cva(\n  'inline-flex h-badge max-w-full items-center whitespace-nowrap rounded-item border border-solid border-border px-gap-control text-xs leading-normal font-medium',\n  {\n    variants: {\n      variant: {\n        default: 'border-transparent bg-primary text-primary-foreground',\n        secondary: 'border-transparent bg-secondary text-secondary-foreground',\n        destructive: 'border-transparent bg-general-error-default text-general-error-on',\n        outline: 'border-input bg-transparent text-foreground',\n        ghost:\n          'border-transparent bg-badge-background-ghost-default text-badge-foreground-ghost-default',\n        subtle:\n          'border-transparent bg-badge-background-subtle-default text-badge-foreground-subtle-default',\n        link: 'border-transparent bg-badge-background-link-default text-badge-foreground-link-default',\n        // Tinted status tones (container fill, on-container text) for read-only status labels.\n        success: 'border-transparent bg-general-success-container text-general-success-on-container',\n        warning: 'border-transparent bg-general-warning-container text-general-warning-on-container',\n        info: 'border-transparent bg-general-info-container text-general-info-on-container',\n        // Credit status tone (data-status-credit subtle fill, on text), matches StatusDot credit.\n        credit: 'border-transparent bg-data-status-credit-subtle text-data-status-credit-on',\n        // workload.zero product colours (Figma Chip Color=product-*): subtle fill, product text, optional border via `bordered`.\n        'product-backoffice': 'border-transparent bg-product-backoffice-subtle',\n        'product-workstream': 'border-transparent bg-product-workstream-subtle',\n        'product-vacancy': 'border-transparent bg-product-vacancy-subtle',\n        'product-jobsearch': 'border-transparent bg-product-jobsearch-subtle',\n        'product-coldcall': 'border-transparent bg-product-coldcall-subtle',\n        // Neutral product accent (slate in light, inverted in dark): readable on its subtle fill in both modes.\n        'product-accent': 'border-transparent bg-product-accent-subtle',\n      },\n      // Tinted form of the solid destructive badge: error container fill with on-container text (status label in a table cell or card).\n      tinted: {\n        true: '',\n      },\n      // Product preset (DesignSystemProvider `preset`). `zero` gives the plain badge the outline look and 8px padding, and the info tone the brand tint.\n      preset: {\n        default: '',\n        zero: '',\n      },\n      // Adds the product border colour to the product-* variants (Figma Outline=True). No effect on other variants.\n      bordered: {\n        true: '',\n      },\n      // Product variants only: neutral foreground text (>= 4.5:1, the default) instead of the product colour, which falls\n      // below AA on its subtle fill (backoffice teal ~3.5:1, accent 2.0:1 in dark). The product tint stays in fill and border.\n      // `readable={false}` opts back into the product colour for decorative use where the text is not the only carrier.\n      readable: {\n        true: '',\n        false: '',\n      },\n    },\n    compoundVariants: [\n      { variant: 'destructive', tinted: true, className: 'bg-background-destructive-subtle text-text-destructive-on-subtle' },\n      { preset: 'zero', className: 'px-2' },\n      { preset: 'zero', variant: 'default', className: 'border-border-default bg-background text-foreground' },\n      { preset: 'zero', variant: 'info', className: 'bg-background-brand-subtle text-text-info-on-subtle' },\n      { variant: 'product-backoffice', bordered: true, className: 'border-product-backoffice-border' },\n      { variant: 'product-backoffice', readable: false, className: 'text-product-backoffice-default' },\n      { variant: 'product-backoffice', readable: true, className: 'text-foreground' },\n      { variant: 'product-workstream', bordered: true, className: 'border-product-workstream-border' },\n      { variant: 'product-workstream', readable: false, className: 'text-product-workstream-default' },\n      { variant: 'product-workstream', readable: true, className: 'text-foreground' },\n      { variant: 'product-vacancy', bordered: true, className: 'border-product-vacancy-border' },\n      { variant: 'product-vacancy', readable: false, className: 'text-product-vacancy-default' },\n      { variant: 'product-vacancy', readable: true, className: 'text-foreground' },\n      { variant: 'product-jobsearch', bordered: true, className: 'border-product-jobsearch-border' },\n      { variant: 'product-jobsearch', readable: false, className: 'text-product-jobsearch-default' },\n      { variant: 'product-jobsearch', readable: true, className: 'text-foreground' },\n      { variant: 'product-coldcall', bordered: true, className: 'border-product-coldcall-border' },\n      { variant: 'product-accent', bordered: true, className: 'border-product-accent-border' },\n      { variant: 'product-coldcall', readable: false, className: 'text-product-coldcall-default' },\n      { variant: 'product-coldcall', readable: true, className: 'text-foreground' },\n      { variant: 'product-accent', readable: true, className: 'text-foreground' },\n      { variant: 'product-accent', readable: false, className: 'text-product-accent-default' },\n    ],\n    defaultVariants: {\n      variant: 'default',\n      readable: true,\n      preset: 'default',\n    },\n  },\n);\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, Omit<VariantProps<typeof badgeVariants>, 'preset'> {\n  // Optional leading icon. Decorative (aria-hidden), sized with the icon tokens. The text carries the meaning.\n  icon?: React.ReactNode;\n  // Small neutral status dot before the text (decorative). Shown instead of `icon` when both are set.\n  dot?: boolean;\n}\n\nfunction Badge({ className, variant, bordered, readable, tinted, icon, dot, children, title, ...props }: BadgeProps) {\n  const zero = usePreset() === 'zero';\n  const hasAdornment = Boolean(icon || dot);\n  const isText = typeof children === 'string' || typeof children === 'number';\n  // Text sits in its own label slot: the badge keeps the 0.25.0 box (inline-flex, fixed height, normal baseline) and only the label truncates, and only when max-w-full is reached. The 4px padding and the matching negative margin keep descenders out of the overflow clip without changing the layout.\n  const text = isText ? String(children) : undefined;\n  return (\n    <div\n      className={cn(\n        badgeVariants({ variant, bordered, readable, tinted, preset: zero ? 'zero' : 'default' }),\n        hasAdornment && 'gap-1',\n        className,\n      )}\n      title={title ?? text}\n      {...props}\n    >\n      {dot ? (\n        <span aria-hidden=\"true\" data-slot=\"dot\" className=\"h-2 w-2 shrink-0 rounded-full bg-icon-subtle\" />\n      ) : icon ? (\n        <span aria-hidden=\"true\" data-slot=\"icon\" className=\"inline-flex shrink-0 [&>svg]:h-icon-xs [&>svg]:w-icon-xs\">\n          {icon}\n        </span>\n      ) : null}\n      {isText ? (\n        <span data-slot=\"label\" className=\"-my-1 min-w-0 truncate py-1\">\n          {children}\n        </span>\n      ) : (\n        children\n      )}\n    </div>\n  );\n}\n\nexport { Badge, badgeVariants };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}