{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "skeleton",
  "type": "registry:ui",
  "registryDependencies": [],
  "dependencies": [],
  "devDependencies": [],
  "files": [
    {
      "path": "skeleton.tsx",
      "content": "\"use client\";\n\nimport {\n  type CSSProperties,\n  forwardRef,\n  type HTMLAttributes,\n  useLayoutEffect,\n} from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst componentThemeClassName =\n  \"[--ic-background:#ffffff] [--ic-foreground:#111111] [--ic-primary:#111111] [--ic-secondary:#646b75] [--ic-surface-border:#e9edf2] [--ic-border:#e3e7ec] [--ic-card:#ffffff] [--ic-card-foreground:#111111] [--ic-muted:#f5f7fa] [--ic-muted-foreground:#6d7480] [--ic-accent:#f3f5f8] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] [--ic-accent-foreground:#111111] [--ic-input:#e3e7ec] [--ic-ring:rgba(17,17,17,0.16)] [--ic-destructive:#dc2626] [--ic-paper:#fcfcfd] [--ic-popover-foreground:#111111] [--ic-brand:#0ea5e9] [--ic-brand-soft:#bae6fd] [--ic-shadow-soft:0_18px_38px_-24px_rgba(15,23,42,0.35)] [--ic-chart-1:oklch(0.52_0.19_254)] [--ic-chart-2:oklch(0.74_0.11_232)] [--ic-chart-3:oklch(0.42_0.16_262)] [--ic-chart-4:oklch(0.84_0.07_228)] [--ic-chart-5:oklch(0.62_0.14_240)] [--color-background:var(--ic-background)] [--color-foreground:var(--ic-foreground)] [--color-primary:var(--ic-primary)] [--color-secondary:var(--ic-secondary)] [--color-border:var(--ic-border)] [--color-card:var(--ic-card)] [--color-card-foreground:var(--ic-card-foreground)] [--color-muted:var(--ic-muted)] [--color-muted-foreground:var(--ic-muted-foreground)] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] [--color-input:var(--ic-input)] [--color-ring:var(--ic-ring)] [--color-destructive:var(--ic-destructive)] [--color-paper:var(--ic-paper)] [--color-popover-foreground:var(--ic-popover-foreground)] [--color-brand:var(--ic-brand)] [--color-brand-soft:var(--ic-brand-soft)] [--color-chart-1:var(--ic-chart-1)] [--color-chart-2:var(--ic-chart-2)] [--color-chart-3:var(--ic-chart-3)] [--color-chart-4:var(--ic-chart-4)] [--color-chart-5:var(--ic-chart-5)] dark:[--ic-background:#111111] dark:[--ic-foreground:#f6f3ec] dark:[--ic-primary:#f6f3ec] dark:[--ic-secondary:#cbc6bb] dark:[--ic-surface-border:#2a2a25] dark:[--ic-border:#2b2a25] dark:[--ic-card:#111111] dark:[--ic-card-foreground:#f6f3ec] dark:[--ic-muted:#171716] dark:[--ic-muted-foreground:#9a958a] dark:[--ic-accent:#1a1a18] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] dark:[--ic-accent-foreground:#f6f3ec] dark:[--ic-input:#2b2a25] dark:[--ic-ring:rgba(246,243,236,0.18)] dark:[--ic-destructive:#f87171] dark:[--ic-paper:#171716] dark:[--ic-popover-foreground:#f6f3ec] dark:[--ic-brand:#38bdf8] dark:[--ic-brand-soft:#0c4a6e] dark:[--ic-shadow-soft:0_20px_44px_-28px_rgba(0,0,0,0.6)] dark:[--ic-chart-1:oklch(0.68_0.17_250)] dark:[--ic-chart-2:oklch(0.82_0.09_225)] dark:[--ic-chart-3:oklch(0.58_0.15_260)] dark:[--ic-chart-4:oklch(0.75_0.12_235)] dark:[--ic-chart-5:oklch(0.88_0.06_220)]\";\n\nconst STYLE_ID = \"iconiq-skeleton-styles\";\n\nconst SKELETON_CSS = `\n@keyframes iconiq-skeleton-shimmer {\n  to {\n    transform: translateX(200%);\n  }\n}\n\n@keyframes iconiq-skeleton-fade {\n  0%,\n  100% {\n    opacity: 1;\n  }\n\n  50% {\n    opacity: 0.38;\n  }\n}\n\n.iconiq-skeleton-surface {\n  background-color: #f5f7fa;\n  background-color: var(--ic-muted);\n}\n\n.iconiq-skeleton-shimmer {\n  background: linear-gradient(\n    90deg,\n    transparent 0%,\n    rgba(17, 17, 17, 0.06) 50%,\n    transparent 100%\n  );\n  background: linear-gradient(\n    90deg,\n    transparent 0%,\n    color-mix(in srgb, var(--ic-foreground) 6%, transparent) 50%,\n    transparent 100%\n  );\n  animation: iconiq-skeleton-shimmer var(--iconiq-skeleton-duration, 1.6s)\n    ease-in-out infinite;\n}\n\n.iconiq-skeleton-fade-root {\n  animation: iconiq-skeleton-fade var(--iconiq-skeleton-duration, 2.4s)\n    ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .iconiq-skeleton-shimmer,\n  .iconiq-skeleton-fade-root {\n    animation: none;\n  }\n}\n`;\n\ntype SkeletonRounded = \"none\" | \"sm\" | \"md\" | \"lg\" | \"full\";\ntype SkeletonVariant = \"shimmer\" | \"fade\";\n\nconst skeletonRoundedClasses = {\n  none: \"rounded-none\",\n  sm: \"rounded-sm\",\n  md: \"rounded-md\",\n  lg: \"rounded-lg\",\n  full: \"rounded-full\",\n} as const satisfies Record<SkeletonRounded, string>;\n\nconst skeletonVariantDefaultDuration: Record<SkeletonVariant, number> = {\n  shimmer: 1.6,\n  fade: 2.4,\n};\n\nfunction getSkeletonVariantDuration(variant: SkeletonVariant, duration = 1.6) {\n  if (duration !== 1.6) {\n    return duration;\n  }\n\n  return skeletonVariantDefaultDuration[variant];\n}\n\nfunction ensureSkeletonStyles() {\n  if (typeof document === \"undefined\") {\n    return;\n  }\n\n  let style = document.getElementById(STYLE_ID) as HTMLStyleElement | null;\n\n  if (!style) {\n    style = document.createElement(\"style\");\n    style.id = STYLE_ID;\n    document.head.appendChild(style);\n  }\n\n  style.textContent = SKELETON_CSS;\n}\n\nfunction resolveSkeletonA11yProps({\n  animate = true,\n  decorative = true,\n  label,\n}: {\n  animate?: boolean;\n  decorative?: boolean;\n  label?: string | null;\n}) {\n  if (decorative || label === null) {\n    return { \"aria-hidden\": true as const };\n  }\n\n  return {\n    \"aria-label\": label ?? (animate ? \"Loading\" : \"Placeholder\"),\n    \"aria-live\": \"polite\" as const,\n    role: \"status\" as const,\n  };\n}\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n  animate?: boolean;\n  decorative?: boolean;\n  duration?: number;\n  label?: string | null;\n  rounded?: SkeletonRounded;\n  variant?: SkeletonVariant;\n}\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(function Skeleton(\n  {\n    animate = true,\n    className,\n    decorative = true,\n    duration = 1.6,\n    label,\n    rounded = \"md\",\n    style,\n    variant = \"shimmer\",\n    ...props\n  },\n  ref\n) {\n  const variantDuration = getSkeletonVariantDuration(variant, duration);\n  const showShimmer = animate && variant === \"shimmer\";\n  const showFade = animate && variant === \"fade\";\n\n  useLayoutEffect(() => {\n    if (animate) {\n      ensureSkeletonStyles();\n    }\n  }, [animate]);\n\n  const animatedStyle =\n    showShimmer || showFade\n      ? ({\n          ...style,\n          \"--iconiq-skeleton-duration\": `${variantDuration}s`,\n        } as CSSProperties)\n      : style;\n\n  return (\n    <div\n      className={cn(\n        componentThemeClassName,\n        \"iconiq-skeleton-surface relative block h-4 w-full overflow-hidden\",\n        showFade && \"iconiq-skeleton-fade-root\",\n        skeletonRoundedClasses[rounded],\n        className\n      )}\n      ref={ref}\n      style={animatedStyle}\n      {...resolveSkeletonA11yProps({ animate, decorative, label })}\n      {...props}\n    >\n      {showShimmer ? (\n        <span\n          aria-hidden=\"true\"\n          className=\"iconiq-skeleton-shimmer pointer-events-none absolute inset-0 -translate-x-full\"\n        />\n      ) : null}\n    </div>\n  );\n});\n\nSkeleton.displayName = \"Skeleton\";\n\nfunction SkeletonAvatar({\n  className,\n  ...props\n}: Omit<SkeletonProps, \"rounded\">) {\n  return (\n    <Skeleton\n      className={cn(\"size-10\", className)}\n      decorative\n      rounded=\"full\"\n      {...props}\n    />\n  );\n}\n\nfunction SkeletonText({ className, ...props }: SkeletonProps) {\n  return <Skeleton className={cn(\"h-3\", className)} decorative {...props} />;\n}\n\nfunction SkeletonButton({\n  className,\n  ...props\n}: Omit<SkeletonProps, \"rounded\">) {\n  return (\n    <Skeleton\n      className={cn(\"h-9 w-24\", className)}\n      decorative\n      rounded=\"lg\"\n      {...props}\n    />\n  );\n}\n\nconst ShimmerSkeleton = Skeleton;\n\nexport {\n  getSkeletonVariantDuration,\n  resolveSkeletonA11yProps,\n  Skeleton,\n  SkeletonAvatar,\n  SkeletonButton,\n  SkeletonText,\n  ShimmerSkeleton,\n  skeletonRoundedClasses,\n  skeletonVariantDefaultDuration,\n};\nexport default Skeleton;\nexport type {\n  SkeletonProps,\n  SkeletonProps as ShimmerSkeletonProps,\n  SkeletonRounded,\n  SkeletonVariant,\n};\n",
      "type": "registry:ui"
    }
  ],
  "title": "Skeleton",
  "description": "Shimmer or fade loading placeholder with preset helpers, configurable radius, optional animation, and embedded theme tokens."
}
