{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "alert-banner",
  "title": "Banner alert",
  "description": "Styled alert: the Banner set. 5 decorative alert variations (TopAlert, InlineAlert, StickyAlert, CompactAlert, BarAlert) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/alert-banner.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport { CircleAlert, CircleCheck, Info, TriangleAlert } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Banner alert family: 5 decorative alert surfaces. The shared idea is an\n   EDGE-TO-EDGE strip - no radius (rounded-none), horizontal lines cross the full\n   width, and the surface reads as a page strip rather than a card. The variants\n   differ by where the strip sits on the page (top, in the flow, sticky,\n   compressed, solid bar). Colour comes ONLY from semantic tokens; alpha via\n   color-mix or the tailwind opacity modifier. Anatomy (Berkay's decision): the\n   icon marks the TITLE ROW ONLY - icon and title share line 1, the description\n   starts BELOW the icon and takes the full width. No motion, this family is\n   entirely static. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nexport type StyledTone = \"info\" | \"success\" | \"warning\" | \"danger\"\n\nconst pad: Record<StyledSize, string> = {\n  sm: \"p-3 text-sm\",\n  md: \"p-4 text-sm\",\n  lg: \"p-4 text-base\",\n  xl: \"p-5 text-base\",\n}\n\n/* Compact uses its own narrower scale - the strip stays close to a single line. */\nconst padCompact: Record<StyledSize, string> = {\n  sm: \"px-3 py-1.5 text-sm\",\n  md: \"px-4 py-2 text-sm\",\n  lg: \"px-5 py-2.5 text-base\",\n  xl: \"px-6 py-3 text-base\",\n}\n\n/* Grid: icon column plus content. The icon is a direct child, so the\n   [&>svg] / [&>i] pair (lucide <svg> and remixicon <i> compatibility) lives\n   here. Because this is a strip, rounded-none is baked into the base. */\nconst base =\n  \"relative grid w-full grid-cols-[calc(var(--spacing)*4)_1fr] items-start gap-x-2 gap-y-0.5 rounded-none [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:translate-y-0.5 [&>i]:block [&>i]:size-4 [&>i]:shrink-0 [&>i]:translate-y-0.5 [&>i]:text-base [&>i]:leading-none\"\n\n/* Tone -> varsayilan lucide ikon. */\nconst toneIcon: Record<StyledTone, React.ReactNode> = {\n  info: <Info />,\n  success: <CircleCheck />,\n  warning: <TriangleAlert />,\n  danger: <CircleAlert />,\n}\n\n/* Icon colour comes from the root; the [&>i] pair is required for remixicon\n   compatibility. */\nconst iconTone: Record<StyledTone, string> = {\n  info: \"[&>svg]:text-info [&>i]:text-info\",\n  success: \"[&>svg]:text-success [&>i]:text-success\",\n  warning: \"[&>svg]:text-warning-soft-foreground [&>i]:text-warning-soft-foreground\",\n  danger: \"[&>svg]:text-danger [&>i]:text-danger\",\n}\n\ntype AlertProps = Omit<React.ComponentProps<\"div\">, \"title\"> & {\n  size?: StyledSize\n  tone?: StyledTone\n  title?: React.ReactNode\n  icon?: React.ReactNode\n}\n\n/* Shared shell: the surface and the size map are supplied from outside. */\nfunction Frame({\n  size,\n  tone,\n  title,\n  icon,\n  children,\n  className,\n  surface,\n  scale = pad,\n  ...props\n}: Omit<AlertProps, \"size\" | \"tone\"> & {\n  size: StyledSize\n  tone: StyledTone\n  surface: string\n  scale?: Record<StyledSize, string>\n}) {\n  return (\n    <div\n      data-slot=\"styled-alert\"\n      data-tone={tone}\n      role=\"alert\"\n      className={cn(base, scale[size], surface, className)}\n      {...props}\n    >\n      {icon ?? toneIcon[tone]}\n      <div\n        data-slot=\"styled-alert-title\"\n        className=\"col-start-2 min-h-4 font-medium tracking-tight\"\n      >\n        {title}\n      </div>\n      <div\n        data-slot=\"styled-alert-description\"\n        className=\"col-span-2 col-start-1 text-sm opacity-90 [&_p]:leading-relaxed\"\n      >\n        {children}\n      </div>\n    </div>\n  )\n}\n\n/* A soft tone ground plus a tone underline. Top, Sticky and Compact share\n   this. */\nconst softTone: Record<StyledTone, string> = {\n  info: \"bg-info-soft text-info-soft-foreground border-info/40\",\n  success: \"bg-success-soft text-success-soft-foreground border-success/40\",\n  warning: \"bg-warning-soft text-warning-soft-foreground border-warning/50\",\n  danger: \"bg-danger-soft text-danger-soft-foreground border-danger/40\",\n}\n\n/* Top: an announcement strip pinned to the very top of the page - underline\n   only. */\nexport function TopAlert({\n  className,\n  size = \"md\",\n  tone = \"info\",\n  title = \"Heads up\",\n  children = \"A page-top notice strip with a single bottom rule.\",\n  icon,\n  ...props\n}: AlertProps) {\n  return (\n    <Frame\n      size={size}\n      tone={tone}\n      title={title}\n      icon={icon}\n      surface={cn(\"border-b\", softTone[tone])}\n      className={className}\n      {...props}\n    >\n      {children}\n    </Frame>\n  )\n}\n\n/* Inline: a neutral strip dropped into the middle of the content flow - a line\n   above and below, colour only in the icon. */\nexport function InlineAlert({\n  className,\n  size = \"md\",\n  tone = \"info\",\n  title = \"Heads up\",\n  children = \"A neutral strip that sits inside the content flow.\",\n  icon,\n  ...props\n}: AlertProps) {\n  return (\n    <Frame\n      size={size}\n      tone={tone}\n      title={title}\n      icon={icon}\n      surface={cn(\"border-y border-border bg-surface-2 text-foreground\", iconTone[tone])}\n      className={className}\n      {...props}\n    >\n      {children}\n    </Frame>\n  )\n}\n\n/* Sticky: a strip that sticks to the top on scroll. Semi-transparent plus a\n   backdrop blur so the content underneath stays readable; falls back to an\n   opaque soft ground where blur is unsupported. */\nconst stickyTone: Record<StyledTone, string> = {\n  info: \"bg-info-soft/85 text-info-soft-foreground border-info/40 supports-[backdrop-filter]:bg-info-soft/60\",\n  success:\n    \"bg-success-soft/85 text-success-soft-foreground border-success/40 supports-[backdrop-filter]:bg-success-soft/60\",\n  warning:\n    \"bg-warning-soft/85 text-warning-soft-foreground border-warning/50 supports-[backdrop-filter]:bg-warning-soft/60\",\n  danger:\n    \"bg-danger-soft/85 text-danger-soft-foreground border-danger/40 supports-[backdrop-filter]:bg-danger-soft/60\",\n}\n\nexport function StickyAlert({\n  className,\n  size = \"md\",\n  tone = \"info\",\n  title = \"Heads up\",\n  children = \"A strip that sticks to the top of its scroll container.\",\n  icon,\n  ...props\n}: AlertProps) {\n  return (\n    <Frame\n      size={size}\n      tone={tone}\n      title={title}\n      icon={icon}\n      surface={cn(\n        \"sticky top-0 z-10 border-b supports-[backdrop-filter]:backdrop-blur-md\",\n        stickyTone[tone]\n      )}\n      className={className}\n      {...props}\n    >\n      {children}\n    </Frame>\n  )\n}\n\n/* Compact: the narrowest strip - for persistent displays such as system\n   status. */\nexport function CompactAlert({\n  className,\n  size = \"md\",\n  tone = \"info\",\n  title = \"Heads up\",\n  children = \"The tightest strip, sized for persistent status.\",\n  icon,\n  ...props\n}: AlertProps) {\n  return (\n    <Frame\n      size={size}\n      tone={tone}\n      title={title}\n      icon={icon}\n      scale={padCompact}\n      surface={cn(\"border-y\", softTone[tone])}\n      className={className}\n      {...props}\n    >\n      {children}\n    </Frame>\n  )\n}\n\n/* Bar: a solid tone bar. The loudest member of the strip family; text and icon\n   come from tone -foreground. */\nconst barTone: Record<StyledTone, string> = {\n  info: \"bg-info text-info-foreground\",\n  success: \"bg-success text-success-foreground\",\n  warning: \"bg-warning text-warning-foreground\",\n  danger: \"bg-danger text-danger-foreground\",\n}\n\nexport function BarAlert({\n  className,\n  size = \"md\",\n  tone = \"info\",\n  title = \"Heads up\",\n  children = \"A saturated edge-to-edge bar in the solid tone.\",\n  icon,\n  ...props\n}: AlertProps) {\n  return (\n    <Frame\n      size={size}\n      tone={tone}\n      title={title}\n      icon={icon}\n      surface={barTone[tone]}\n      className={className}\n      {...props}\n    >\n      {children}\n    </Frame>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/alert-banner.tsx"
    }
  ],
  "categories": [
    "styled",
    "alert"
  ],
  "type": "registry:component"
}