{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"data","type":"registry:lib","title":"Data","author":"Eduardo Calvo <educlopez93@gmail.com>","dependencies":[],"devDependencies":[],"registryDependencies":[],"files":[{"type":"registry:lib","path":"component-meta.ts","content":"/**\n * Component metadata types for AI-first developer experience.\n *\n * These types define structured, machine-readable metadata for SmoothUI\n * components and blocks, enabling AI agents to discover, filter, and\n * understand components without reading source code.\n */\n\n// ---------------------------------------------------------------------------\n// Category types\n// ---------------------------------------------------------------------------\n\nexport type ComponentCategory =\n  | \"basic-ui\"\n  | \"button\"\n  | \"text\"\n  | \"ai\"\n  | \"layout\"\n  | \"feedback\"\n  | \"data-display\"\n  | \"navigation\"\n  | \"other\";\n\nexport type AnimationType = \"spring\" | \"tween\" | \"gesture\" | \"scroll\" | \"none\";\n\nexport type Complexity = \"simple\" | \"moderate\" | \"complex\";\n\n// ---------------------------------------------------------------------------\n// Component metadata\n// ---------------------------------------------------------------------------\n\n/**\n * Full metadata for a single SmoothUI component.\n *\n * Combines data from two sources:\n * - `smoothui` field in the component's package.json (authored by hand)\n * - MDX frontmatter and registry info (derived at build time)\n */\nexport interface ComponentMeta {\n  /** Dominant animation technique */\n  animationType: AnimationType;\n  /** Primary UI category */\n  category: ComponentCategory;\n  /** Rough complexity level */\n  complexity: Complexity;\n  /** Hints for combining with other components */\n  compositionHints: readonly string[];\n  /** npm packages required (excluding peer deps) */\n  dependencies: readonly string[];\n  /** 1-2 sentence human-readable description */\n  description: string;\n  /** PascalCase display name, e.g. \"AnimatedTabs\" */\n  displayName: string;\n  /** Full documentation URL */\n  docUrl: string;\n  /** Whether the component respects prefers-reduced-motion */\n  hasReducedMotion: boolean;\n  /** shadcn-style install command */\n  installCommand: string;\n  /** kebab-case identifier, e.g. \"animated-tabs\" */\n  name: string;\n  /** Number of public props */\n  propsCount: number;\n  /** Other SmoothUI components required */\n  registryDependencies: readonly string[];\n  /** Registry JSON URL */\n  registryUrl: string;\n  /** Discoverable tags, e.g. [\"animation\", \"tabs\", \"navigation\"] */\n  tags: readonly string[];\n  /** Natural-language use-case descriptions */\n  useCases: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// Block metadata\n// ---------------------------------------------------------------------------\n\nexport type BlockType =\n  | \"hero\"\n  | \"features\"\n  | \"pricing\"\n  | \"testimonials\"\n  | \"cta\"\n  | \"footer\"\n  | \"header\"\n  | \"other\";\n\n/**\n * Full metadata for a pre-built page block (section).\n */\nexport interface BlockMeta {\n  /** Dominant animation technique */\n  animationType: AnimationType;\n  /** Block section type */\n  blockType: BlockType;\n  /** Primary UI category */\n  category: ComponentCategory;\n  /** Rough complexity level */\n  complexity: Complexity;\n  /** SmoothUI components used inside this block */\n  components: readonly string[];\n  /** npm packages required */\n  dependencies: readonly string[];\n  /** 1-2 sentence description */\n  description: string;\n  /** PascalCase display name */\n  displayName: string;\n  /** Full documentation URL */\n  docUrl: string;\n  /** Whether the block respects prefers-reduced-motion */\n  hasReducedMotion: boolean;\n  /** shadcn-style install command */\n  installCommand: string;\n  /** kebab-case identifier */\n  name: string;\n  /** Registry JSON URL */\n  registryUrl: string;\n  /** Discoverable tags */\n  tags: readonly string[];\n  /** Natural-language use-case descriptions */\n  useCases: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// API response types\n// ---------------------------------------------------------------------------\n\n/**\n * Paginated list response wrapper used by all list endpoints.\n */\nexport interface PaginatedResponse<T> {\n  data: T[];\n  page: number;\n  pageSize: number;\n  total: number;\n  totalPages: number;\n}\n\n/** GET /api/components */\nexport type ComponentListResponse = PaginatedResponse<ComponentMeta>;\n\n/** GET /api/components/:name */\nexport interface ComponentDetailResponse {\n  component: ComponentMeta;\n  /** Raw source code (optional, included when ?include=source) */\n  source?: string;\n}\n\n/** GET /api/blocks */\nexport type BlockListResponse = PaginatedResponse<BlockMeta>;\n\n/** GET /api/blocks/:name */\nexport interface BlockDetailResponse {\n  block: BlockMeta;\n  source?: string;\n}\n\n/** Standard error envelope returned by API routes */\nexport interface ApiErrorResponse {\n  error: string;\n  status: number;\n}\n\n// ---------------------------------------------------------------------------\n// Query / filter helpers\n// ---------------------------------------------------------------------------\n\n/** Supported filter parameters for component list queries */\nexport interface ComponentQueryParams {\n  animationType?: AnimationType;\n  category?: ComponentCategory;\n  complexity?: Complexity;\n  page?: number;\n  pageSize?: number;\n  search?: string;\n  tag?: string;\n}\n\n/** Supported filter parameters for block list queries */\nexport interface BlockQueryParams {\n  blockType?: BlockType;\n  complexity?: Complexity;\n  page?: number;\n  pageSize?: number;\n  search?: string;\n  tag?: string;\n}\n","target":"lib/smoothui-data/component-meta.ts"},{"type":"registry:lib","path":"index.ts","content":"// ---------------------------------------------------------------------------\n// AI-first metadata types & schema\n// ---------------------------------------------------------------------------\nexport type {\n  AnimationType,\n  ApiErrorResponse,\n  BlockDetailResponse,\n  BlockListResponse,\n  BlockMeta,\n  BlockQueryParams,\n  BlockType,\n  Complexity,\n  ComponentCategory,\n  ComponentDetailResponse,\n  ComponentListResponse,\n  ComponentMeta,\n  ComponentQueryParams,\n  PaginatedResponse,\n} from \"./component-meta\";\n\nexport type {\n  ParseFailure,\n  ParseResult,\n  ParseSuccess,\n  SmoothUIPackageMeta,\n} from \"./smoothui-schema\";\n\nexport { parseSmoothUIMeta } from \"./smoothui-schema\";\n\n// ---------------------------------------------------------------------------\n// People data\n// ---------------------------------------------------------------------------\n\n/**\n * Unified Person interface for all people data\n *\n * This single interface contains all possible fields for people data.\n * Components can use only the fields they need:\n * - Team components: name, role, bio, avatar, location, experience, social, company\n * - Testimonial components: name, role, avatar, stars, content\n * - Mixed components: any combination of fields\n */\nexport interface Person {\n  avatar: string;\n  bio?: string;\n  company?: string;\n  content?: string;\n  experience?: string;\n  location?: string;\n  name: string;\n  role: string;\n  social?: {\n    twitter?: string;\n    linkedin?: string;\n    github?: string;\n    website?: string;\n  };\n  // Testimonial specific fields\n  stars?: number;\n}\n\nexport const peopleData: Person[] = [\n  {\n    name: \"Eduardo Calvo\",\n    role: \"CEO & Founder\",\n    bio: \"Passionate about building products that make a difference. Leading the vision for innovative user experiences.\",\n    avatar:\n      \"https://ik.imagekit.io/16u211libb/avatar-educalvolpz.jpeg?updatedAt=1765524159631\",\n    location: \"Spain\",\n    experience: \"8+ years of experience\",\n    company: \"SmoothUI\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n    stars: 5,\n    content:\n      \"SmoothUI has revolutionized how we build user interfaces. The animations are buttery smooth and the developer experience is incredible.\",\n  },\n  {\n    name: \"Drew Cano\",\n    role: \"Head of Design\",\n    bio: \"Creating beautiful and intuitive user experiences that users love. Passionate about design systems and accessibility.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar.jpg\",\n    location: \"San Francisco, CA\",\n    experience: \"7+ years of experience\",\n    company: \"Design Studio\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n    stars: 5,\n    content:\n      \"The design system is incredibly well thought out. Every component feels intentional and polished.\",\n  },\n  {\n    name: \"Marcus Johnson\",\n    role: \"Lead Developer\",\n    bio: \"Building scalable solutions for modern applications. Expert in React, TypeScript, and cloud architecture.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-1.jpg\",\n    location: \"Austin, TX\",\n    experience: \"10+ years of experience\",\n    company: \"TechCorp\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n    stars: 5,\n    content:\n      \"Best UI library I've used. The TypeScript support is excellent and the components are highly customizable.\",\n  },\n  {\n    name: \"Emily Rodriguez\",\n    role: \"Product Manager\",\n    bio: \"Driving product strategy and user research to create products that truly solve user problems.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-2.jpg\",\n    location: \"New York, NY\",\n    experience: \"6+ years of experience\",\n    company: \"ProductCo\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n    stars: 4,\n    content:\n      \"Our users love the smooth interactions. It's made our product feel premium and professional.\",\n  },\n  {\n    name: \"Mollie Hall\",\n    role: \"CTO\",\n    bio: \"Full-stack engineer with expertise in distributed systems and team leadership. Building the future of technology.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-3.jpg\",\n    location: \"Seattle, WA\",\n    experience: \"12+ years of experience\",\n    company: \"InnovateTech\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n    stars: 5,\n    content:\n      \"The performance is outstanding. Our bundle size stayed the same while getting beautiful animations.\",\n  },\n  {\n    name: \"Alec Whitten\",\n    role: \"UX Researcher\",\n    bio: \"Understanding user behavior and needs to inform design decisions. Passionate about creating inclusive experiences.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-4.jpg\",\n    location: \"Toronto, Canada\",\n    experience: \"5+ years of experience\",\n    company: \"ResearchLab\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n    stars: 5,\n    content:\n      \"The accessibility features are top-notch. Every component follows WCAG guidelines perfectly.\",\n  },\n  {\n    name: \"Alisa Hester\",\n    role: \"Frontend Engineer\",\n    bio: \"Specializing in React, animations, and performance optimization. Creating smooth user experiences.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-5.jpg\",\n    location: \"London, UK\",\n    experience: \"4+ years of experience\",\n    company: \"WebStudio\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n  },\n  {\n    name: \"Johnny Bell\",\n    role: \"Backend Engineer\",\n    bio: \"Building robust APIs and microservices. Expert in Node.js, Python, and cloud infrastructure.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-6.jpg\",\n    location: \"Barcelona, Spain\",\n    experience: \"6+ years of experience\",\n    company: \"BackendPro\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n  },\n  {\n    name: \"Mia Ward\",\n    role: \"DevOps Engineer\",\n    bio: \"Automating deployments and ensuring system reliability. Passionate about infrastructure as code.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-7.jpg\",\n    location: \"Berlin, Germany\",\n    experience: \"8+ years of experience\",\n    company: \"CloudOps\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n  },\n  {\n    name: \"Josh Knight\",\n    role: \"Marketing Director\",\n    bio: \"Driving growth through strategic marketing and community building. Expert in developer relations.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-8.jpg\",\n    location: \"Singapore\",\n    experience: \"7+ years of experience\",\n    company: \"GrowthCo\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n  },\n\n  {\n    name: \"Kelly Myer\",\n    role: \"Creator of Sand/UI\",\n    bio: \"Building beautiful and accessible UI components for React developers.\",\n    avatar: \"https://ik.imagekit.io/16u211libb/smoothui/avatar-9.jpg\",\n    location: \"Remote\",\n    experience: \"5+ years of experience\",\n    company: \"sand/ui\",\n    social: {\n      twitter: \"https://twitter.com/educalvolpz\",\n      linkedin: \"https://linkedin.com/in/educlopez\",\n      github: \"https://github.com/educlopez\",\n      website: \"https://educalvolopez.com\",\n    },\n    stars: 5,\n    content: \"SmoothUI is my go-to for fast, beautiful UIs.\",\n  },\n];\n\n// Get people who have testimonials (stars and content)\nexport const testimonialsData: Person[] = peopleData.filter(\n  (person) => person.stars && person.content\n);\n\ninterface ImageKitOptions {\n  format?: \"auto\" | \"webp\" | \"jpg\" | \"jpeg\" | \"png\" | \"avif\";\n  height?: number;\n  quality?: number;\n  transformations?: string;\n  width?: number;\n}\n\n/**\n * Build transformation string from options\n */\nfunction buildTransformations(options?: ImageKitOptions): string {\n  if (options?.transformations) {\n    return options.transformations;\n  }\n\n  const parts: string[] = [];\n\n  if (options?.width) {\n    parts.push(`w-${options.width}`);\n  }\n  if (options?.height) {\n    parts.push(`h-${options.height}`);\n  }\n\n  const quality = options?.quality ?? 80;\n  parts.push(`q-${quality}`);\n\n  const format = options?.format ?? \"auto\";\n  parts.push(`f-${format}`);\n\n  return parts.join(\",\");\n}\n\n/**\n * Process full URL and add transformations\n */\nfunction processFullUrl(imagePath: string, transformations: string): string {\n  const url = new URL(imagePath);\n  url.searchParams.delete(\"updatedAt\");\n  const baseUrl = url.origin + url.pathname;\n\n  if (!transformations) {\n    return baseUrl;\n  }\n  return `${baseUrl}?tr=${transformations}`;\n}\n\n/**\n * Build local path URL\n */\nfunction buildLocalPathUrl(imagePath: string, transformations: string): string {\n  const endpoint =\n    process.env.NEXT_PUBLIC_IMAGEKIT_URL_ENDPOINT ||\n    process.env.IMAGEKIT_URL_ENDPOINT ||\n    \"https://ik.imagekit.io/16u211libb\";\n\n  const cleanPath = imagePath.startsWith(\"/\") ? imagePath.slice(1) : imagePath;\n\n  const imageKitPath = cleanPath.startsWith(\"images/\")\n    ? `smoothui/${cleanPath.replace(\"images/\", \"\")}`\n    : `smoothui/${cleanPath}`;\n\n  const baseUrl = `${endpoint}/${imageKitPath}`;\n\n  if (transformations) {\n    return `${baseUrl}?tr=${transformations}`;\n  }\n\n  return baseUrl;\n}\n\n/**\n * Get ImageKit URL for an image with optimized transformations\n * Converts local image paths (/images/...) to ImageKit URLs with bandwidth optimization\n * @param imagePath - Local image path (e.g., \"/images/avatar.jpg\") or already full URL\n * @param options - Optional transformation options\n * @param options.width - Image width in pixels\n * @param options.height - Image height in pixels\n * @param options.quality - Image quality (1-100, default: 80)\n * @param options.format - Image format (auto, webp, jpg, png, etc.)\n * @param options.transformations - Raw transformation string (overrides other options)\n * @returns Full ImageKit URL with optimized transformations\n */\nexport function getImageKitUrl(\n  imagePath: string,\n  options?: ImageKitOptions\n): string {\n  const transformations = buildTransformations(options);\n\n  if (imagePath.startsWith(\"http://\") || imagePath.startsWith(\"https://\")) {\n    return processFullUrl(imagePath, transformations);\n  }\n\n  return buildLocalPathUrl(imagePath, transformations);\n}\n\n/**\n * Helper function to get avatar URL with optimized size and quality\n * @param avatar - Avatar image path or URL\n * @param size - Avatar size in pixels (default: 40, will be doubled for retina)\n * @returns Optimized ImageKit URL for avatar\n */\nexport function getAvatarUrl(avatar: string, size = 40): string {\n  // Double the size for retina displays, use higher quality for avatars\n  const retinaSize = size * 2;\n  return getImageKitUrl(avatar, {\n    width: retinaSize,\n    height: retinaSize,\n    quality: 85, // Higher quality for faces\n    format: \"auto\",\n  });\n}\n\n// Helper function to get team member data (people without testimonials or all people)\nexport function getTeamMembers(\n  count = 4,\n  includeTestimonials = false\n): Person[] {\n  if (includeTestimonials) {\n    return peopleData.slice(0, count);\n  }\n  // Return people who don't have testimonials for team display\n  return peopleData\n    .filter((person) => !(person.stars && person.content))\n    .slice(0, count);\n}\n\n// Helper function to get testimonials data\nexport function getTestimonials(count = 4): Person[] {\n  return testimonialsData.slice(0, count);\n}\n\n// Helper function to get all people data\nexport function getAllPeople(): Person[] {\n  return peopleData;\n}\n\n// Helper function to get people by role\nexport function getPeopleByRole(role: string): Person[] {\n  return peopleData.filter((person) =>\n    person.role.toLowerCase().includes(role.toLowerCase())\n  );\n}\n\n// Helper function to get people with testimonials\nexport function getPeopleWithTestimonials(): Person[] {\n  return testimonialsData;\n}\n","target":"lib/smoothui-data/index.ts"},{"type":"registry:lib","path":"smoothui-schema.ts","content":"/**\n * Schema definition and validation for the `smoothui` field in component\n * package.json files.\n *\n * Each component's package.json may include a `smoothui` object with\n * machine-readable metadata. This module provides the TypeScript type for\n * that field and a runtime validation/parsing function.\n *\n * @example package.json\n * ```json\n * {\n *   \"name\": \"@repo/animated-tabs\",\n *   \"description\": \"Animated tabs component with sliding indicator\",\n *   \"smoothui\": {\n *     \"category\": \"navigation\",\n *     \"tags\": [\"animation\", \"tabs\", \"navigation\"],\n *     \"complexity\": \"moderate\",\n *     \"animationType\": \"spring\",\n *     \"useCases\": [\n *       \"Tab navigation with smooth transitions\",\n *       \"Section switcher with animated indicator\"\n *     ],\n *     \"compositionHints\": [\n *       \"Combine with animated-tooltip for rich tab headers\"\n *     ],\n *     \"hasReducedMotion\": true\n *   }\n * }\n * ```\n */\n\nimport type {\n  AnimationType,\n  Complexity,\n  ComponentCategory,\n} from \"./component-meta\";\n\n// ---------------------------------------------------------------------------\n// Schema type\n// ---------------------------------------------------------------------------\n\n/**\n * Shape of the `smoothui` field inside a component's package.json.\n * Only includes metadata that is authored by hand — derived fields\n * (name, displayName, dependencies, URLs) are computed at build time.\n */\nexport interface SmoothUIPackageMeta {\n  /** Dominant animation technique */\n  animationType: AnimationType;\n  /** Primary UI category */\n  category: ComponentCategory;\n  /** Rough complexity level */\n  complexity: Complexity;\n  /** Hints for combining with other components */\n  compositionHints: string[];\n  /** Whether the component respects prefers-reduced-motion */\n  hasReducedMotion: boolean;\n  /** Discoverable tags */\n  tags: string[];\n  /** Natural-language use-case descriptions */\n  useCases: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Validation constants\n// ---------------------------------------------------------------------------\n\nconst VALID_CATEGORIES: readonly ComponentCategory[] = [\n  \"basic-ui\",\n  \"button\",\n  \"text\",\n  \"ai\",\n  \"layout\",\n  \"feedback\",\n  \"data-display\",\n  \"navigation\",\n  \"other\",\n];\n\nconst VALID_COMPLEXITIES: readonly Complexity[] = [\n  \"simple\",\n  \"moderate\",\n  \"complex\",\n];\n\nconst VALID_ANIMATION_TYPES: readonly AnimationType[] = [\n  \"spring\",\n  \"tween\",\n  \"gesture\",\n  \"scroll\",\n  \"none\",\n];\n\n// ---------------------------------------------------------------------------\n// Validation helpers\n// ---------------------------------------------------------------------------\n\ninterface ValidationError {\n  field: string;\n  message: string;\n}\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\n\nconst isBoolean = (value: unknown): value is boolean =>\n  typeof value === \"boolean\";\n\nconst isStringArray = (value: unknown): value is string[] =>\n  Array.isArray(value) && value.every(isString);\n\nconst isOneOf = <T extends string>(\n  value: unknown,\n  allowed: readonly T[]\n): value is T =>\n  isString(value) && (allowed as readonly string[]).includes(value);\n\n// ---------------------------------------------------------------------------\n// Parse result\n// ---------------------------------------------------------------------------\n\nexport interface ParseSuccess {\n  data: SmoothUIPackageMeta;\n  success: true;\n}\n\nexport interface ParseFailure {\n  errors: ValidationError[];\n  success: false;\n}\n\nexport type ParseResult = ParseSuccess | ParseFailure;\n\n// ---------------------------------------------------------------------------\n// Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Validate and parse a raw `smoothui` field from a component package.json.\n *\n * Returns a discriminated union so callers can handle errors explicitly.\n *\n * @param raw - The unknown value read from `packageJson.smoothui`\n * @returns A `ParseResult` with either typed data or a list of errors\n */\nexport const parseSmoothUIMeta = (raw: unknown): ParseResult => {\n  const errors: ValidationError[] = [];\n\n  if (raw === null || raw === undefined || typeof raw !== \"object\") {\n    return {\n      success: false,\n      errors: [{ field: \"smoothui\", message: \"Must be a non-null object\" }],\n    };\n  }\n\n  const obj = raw as Record<string, unknown>;\n\n  // category — required\n  if (!isOneOf(obj.category, VALID_CATEGORIES)) {\n    errors.push({\n      field: \"category\",\n      message: `Must be one of: ${VALID_CATEGORIES.join(\", \")}`,\n    });\n  }\n\n  // tags — required string[]\n  if (!isStringArray(obj.tags)) {\n    errors.push({\n      field: \"tags\",\n      message: \"Must be an array of strings\",\n    });\n  }\n\n  // complexity — required\n  if (!isOneOf(obj.complexity, VALID_COMPLEXITIES)) {\n    errors.push({\n      field: \"complexity\",\n      message: `Must be one of: ${VALID_COMPLEXITIES.join(\", \")}`,\n    });\n  }\n\n  // animationType — required\n  if (!isOneOf(obj.animationType, VALID_ANIMATION_TYPES)) {\n    errors.push({\n      field: \"animationType\",\n      message: `Must be one of: ${VALID_ANIMATION_TYPES.join(\", \")}`,\n    });\n  }\n\n  // useCases — required string[]\n  if (!isStringArray(obj.useCases)) {\n    errors.push({\n      field: \"useCases\",\n      message: \"Must be an array of strings\",\n    });\n  }\n\n  // compositionHints — required string[]\n  if (!isStringArray(obj.compositionHints)) {\n    errors.push({\n      field: \"compositionHints\",\n      message: \"Must be an array of strings\",\n    });\n  }\n\n  // hasReducedMotion — required boolean\n  if (!isBoolean(obj.hasReducedMotion)) {\n    errors.push({\n      field: \"hasReducedMotion\",\n      message: \"Must be a boolean\",\n    });\n  }\n\n  if (errors.length > 0) {\n    return { success: false, errors };\n  }\n\n  return {\n    success: true,\n    data: {\n      category: obj.category as ComponentCategory,\n      tags: obj.tags as string[],\n      complexity: obj.complexity as Complexity,\n      animationType: obj.animationType as AnimationType,\n      useCases: obj.useCases as string[],\n      compositionHints: obj.compositionHints as string[],\n      hasReducedMotion: obj.hasReducedMotion as boolean,\n    },\n  };\n};\n","target":"lib/smoothui-data/smoothui-schema.ts"}],"css":{}}