{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "featured-icon",
  "title": "Featured Icon",
  "description": "The Untitled-UI-style icon-in-a-decorative-container, used atop empty states and alerts.",
  "registryDependencies": [
    "@nx-ui/utils"
  ],
  "files": [
    {
      "path": "components/blocks/featured-icon.tsx",
      "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/**\n * FeaturedIcon — the Untitled UI signature \"icon in a decorative container\",\n * used at the top of empty states, modals, alerts and feature lists.\n *\n * Six themes, all token-driven so they flip correctly in dark mode:\n *   - `light`    — soft colour tint + mid-strength icon (the common default).\n *   - `gradient` — the glowy pill: a faint outer ring + a solid gradient core.\n *   - `dark`     — an embossed dark chip with a skeuomorphic inner edge.\n *   - `modern`   — a neutral white \"card\" icon with a hairline ring (used by\n *                  file-upload and empty-state by default).\n *   - `modern-neue` — modern with a layered multi-shadow soft-emboss.\n *   - `outline`  — concentric fading rings around a small icon (target reticle).\n *\n * Five semantic colours (brand / gray / error / warning / success) × four\n * sizes (sm / md / lg / xl). The icon is passed as `icon` (a component or a\n * node); it is tagged `data-icon` so the per-theme size selectors apply.\n */\n\nconst iconSizes = {\n  sm: \"*:data-[icon]:size-4 *:data-[icon]:stroke-[2.25px]\",\n  md: \"*:data-[icon]:size-5\",\n  lg: \"*:data-[icon]:size-6\",\n  xl: \"*:data-[icon]:size-7\",\n} as const\n\ntype Theme =\n  | \"light\"\n  | \"gradient\"\n  | \"dark\"\n  | \"modern\"\n  | \"modern-neue\"\n  | \"outline\"\ntype Color = \"brand\" | \"gray\" | \"error\" | \"warning\" | \"success\"\ntype Size = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst styles: Record<\n  Theme,\n  { base: string; sizes: Record<Size, string>; colors: Record<Color, string> }\n> = {\n  light: {\n    base: \"rounded-full\",\n    sizes: {\n      sm: \"size-8\",\n      md: \"size-10\",\n      lg: \"size-12\",\n      xl: \"size-14\",\n    },\n    colors: {\n      brand: \"bg-bg-brand-secondary text-featured-icon-light-fg-brand\",\n      gray: \"bg-bg-tertiary text-featured-icon-light-fg-gray\",\n      error: \"bg-bg-error-secondary text-featured-icon-light-fg-error\",\n      warning: \"bg-bg-warning-secondary text-featured-icon-light-fg-warning\",\n      success: \"bg-bg-success-secondary text-featured-icon-light-fg-success\",\n    },\n  },\n\n  gradient: {\n    base: \"rounded-full text-fg-white before:absolute before:inset-0 before:size-full before:rounded-full before:border before:mask-b-from-0% after:absolute after:block after:rounded-full\",\n    sizes: {\n      sm: \"size-8 after:size-6 *:data-[icon]:size-4\",\n      md: \"size-10 after:size-7 *:data-[icon]:size-4\",\n      lg: \"size-12 after:size-8 *:data-[icon]:size-5\",\n      xl: \"size-14 after:size-10 *:data-[icon]:size-5\",\n    },\n    colors: {\n      brand:\n        \"text-fg-on-brand-solid before:border-utility-brand-200 before:bg-utility-brand-50 after:bg-bg-brand-solid\",\n      gray: \"before:border-utility-neutral-200 before:bg-utility-neutral-50 after:bg-bg-secondary-solid\",\n      error:\n        \"before:border-utility-red-200 before:bg-utility-red-50 after:bg-bg-error-solid\",\n      warning:\n        \"before:border-utility-yellow-200 before:bg-utility-yellow-50 after:bg-bg-warning-solid\",\n      success:\n        \"before:border-utility-green-200 before:bg-utility-green-50 after:bg-bg-success-solid\",\n    },\n  },\n\n  dark: {\n    base: \"text-fg-white shadow-xs-skeuomorphic before:absolute before:inset-px before:border before:border-white/12 before:mask-b-from-0%\",\n    sizes: {\n      sm: \"size-8 rounded-md before:rounded-[5px]\",\n      md: \"size-10 rounded-lg before:rounded-[7px]\",\n      lg: \"size-12 rounded-[10px] before:rounded-[9px]\",\n      xl: \"size-14 rounded-xl before:rounded-[11px]\",\n    },\n    colors: {\n      brand: \"bg-bg-brand-solid text-fg-on-brand-solid before:border-utility-brand-200/12\",\n      gray: \"bg-bg-secondary-solid before:border-utility-neutral-200/12\",\n      error: \"bg-bg-error-solid before:border-utility-red-200/12\",\n      warning: \"bg-bg-warning-solid before:border-utility-yellow-200/12\",\n      success: \"bg-bg-success-solid before:border-utility-green-200/12\",\n    },\n  },\n\n  modern: {\n    base: \"bg-bg-primary shadow-xs-skeuomorphic ring-1 ring-border-primary ring-inset\",\n    sizes: {\n      sm: \"size-8 rounded-md\",\n      md: \"size-10 rounded-lg\",\n      lg: \"size-12 rounded-[10px]\",\n      xl: \"size-14 rounded-xl\",\n    },\n    colors: {\n      brand: \"text-fg-brand-primary\",\n      gray: \"text-fg-secondary\",\n      error: \"text-fg-error-primary\",\n      warning: \"text-fg-warning-primary\",\n      success: \"text-fg-success-primary\",\n    },\n  },\n\n  \"modern-neue\": {\n    base: \"bg-bg-primary_alt ring-1 ring-inset ring-border-primary before:absolute before:inset-1 before:shadow-[0px_1px_2px_0px_rgba(0,0,0,0.1),0px_3px_3px_0px_rgba(0,0,0,0.09),1px_8px_5px_0px_rgba(0,0,0,0.05),2px_21px_6px_0px_rgba(0,0,0,0),0px_0px_0px_1px_rgba(0,0,0,0.08),1px_13px_5px_0px_rgba(0,0,0,0.01),0px_-2px_2px_0px_rgba(0,0,0,0.13)_inset] before:ring-1 before:ring-border-secondary_alt\",\n    sizes: {\n      sm: \"size-8 rounded-[8px] before:rounded-[4px]\",\n      md: \"size-10 rounded-[10px] before:rounded-[6px]\",\n      lg: \"size-12 rounded-[12px] before:rounded-[8px]\",\n      xl: \"size-14 rounded-[14px] before:rounded-[10px]\",\n    },\n    colors: {\n      brand: \"text-fg-brand-primary\",\n      gray: \"text-fg-secondary\",\n      error: \"text-fg-error-primary\",\n      warning: \"text-fg-warning-primary\",\n      success: \"text-fg-success-primary\",\n    },\n  },\n\n  outline: {\n    base: \"before:absolute before:rounded-full before:border-2 after:absolute after:rounded-full after:border-2\",\n    sizes: {\n      sm: \"size-4 before:size-6 after:size-8.5\",\n      md: \"size-5 before:size-7 after:size-9.5\",\n      lg: \"size-6 before:size-8 after:size-10.5\",\n      xl: \"size-7 before:size-9 after:size-11.5\",\n    },\n    colors: {\n      brand:\n        \"text-fg-brand-primary before:border-fg-brand-primary/30 after:border-fg-brand-primary/10\",\n      gray: \"text-fg-tertiary before:border-fg-tertiary/30 after:border-fg-tertiary/10\",\n      error:\n        \"text-fg-error-primary before:border-fg-error-primary/30 after:border-fg-error-primary/10\",\n      warning:\n        \"text-fg-warning-primary before:border-fg-warning-primary/30 after:border-fg-warning-primary/10\",\n      success:\n        \"text-fg-success-primary before:border-fg-success-primary/30 after:border-fg-success-primary/10\",\n    },\n  },\n}\n\nfunction FeaturedIcon({\n  icon: Icon,\n  color = \"brand\",\n  size = \"md\",\n  theme = \"light\",\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  icon?: React.ComponentType<{ className?: string }> | React.ReactNode\n  color?: Color\n  size?: Size\n  theme?: Theme\n}) {\n  const isComponent = typeof Icon === \"function\"\n\n  return (\n    <div\n      data-slot=\"featured-icon\"\n      data-theme={theme}\n      className={cn(\n        \"relative flex shrink-0 items-center justify-center\",\n        iconSizes[size],\n        styles[theme].base,\n        styles[theme].sizes[size],\n        styles[theme].colors[color],\n        className\n      )}\n      {...props}\n    >\n      {isComponent\n        ? React.createElement(Icon as React.ComponentType<{ className?: string; \"data-icon\"?: string }>, {\n            \"data-icon\": \"\",\n            className: \"relative z-[1]\",\n          })\n        : Icon\n          ? <div data-icon=\"\" className=\"relative z-[1]\">{Icon}</div>\n          : null}\n      {children}\n    </div>\n  )\n}\n\nexport { FeaturedIcon }\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:block"
}