{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "utils",
  "title": "Utils",
  "description": "Helper used by the Get IT Done components.",
  "dependencies": [
    "clsx@^2.0.0",
    "tailwind-merge@^2.0.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/lib/utils.ts",
      "content": "import { type ClassValue, clsx } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n// Font sizes the design tokens preset adds on top of Tailwind's scale (theme.fontSize).\n// tailwind-merge only knows the default sizes and treats any other `text-*` as a color, so e.g. `text-ui`\n// would silently drop `text-text-muted`. utils.test.ts asserts this list matches the installed preset.\nexport const TOKEN_FONT_SIZES = [\n  '0',\n  '1',\n  '2',\n  '3',\n  '4',\n  '5',\n  '6',\n  '7',\n  '8',\n  'clamp-small',\n  'clamp',\n  'clamp-large',\n  'clamp-xlarge',\n  'nano',\n  'micro',\n  'ui',\n  'ui-lg',\n  'title-sm',\n  'title-md',\n  'display-sm',\n  'display',\n  'title-lg',\n  'display-md',\n  'file-tag',\n  'logo-tile-20',\n  'logo-tile-24',\n  'logo-tile-32',\n  'logo-tile-40',\n  'logo-tile-48',\n];\n\n// Named spacing tokens of the preset, so size, padding and gap overrides (`px-0` over `px-control-px-sm`) win over the token utilities.\nconst TOKEN_SPACING = [\n  'micro', 'label', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl',\n  'control-xs', 'control-sm', 'control-md', 'control-lg', 'control-xl', 'control-2xl',\n  'control-px-sm', 'control-px-md', 'control-px-lg', 'control-px-xl', 'control-px-2xl', 'control-py-sm', 'control-py-md',\n  'gap-control', 'gap-label',\n  'icon-2xs', 'icon-xs', 'icon-sm', 'icon-md', 'icon-lg', 'icon-tile',\n  'avatar-xs', 'avatar-sm', 'avatar-md', 'avatar-lg', 'avatar-xl', 'avatar-2xl',\n  'checkbox-sm', 'checkbox-md', 'topbar', 'topbar-lg', 'toolbar', 'time-axis',\n  'switch-track-w-sm', 'switch-track-h-sm', 'switch-track-w-md', 'switch-track-h-md', 'switch-thumb-sm', 'switch-thumb-md',\n  'calendar-cell', 'month-cell', 'heatmap-cell', 'tree-indent', 'swatch-sm', 'swatch-md', 'brand-mark-sm', 'progress-md', 'kbd', 'object-icon', 'stepper-marker',\n  'status-dot', 'badge', 'button-px-sm', 'button-gap-sm',\n];\n\nconst twMerge = extendTailwindMerge<'typography'>({\n  extend: {\n    theme: { spacing: TOKEN_SPACING },\n    classGroups: {\n      'font-size': [{ text: TOKEN_FONT_SIZES }],\n      // Token radius tiers and the `font-regular` weight, so variants can override the base.\n      rounded: [{ rounded: ['item', 'control', 'surface', 'dialog', 'popover'] }],\n      // Focus ring widths of the preset (ring-focus 2px, ring-halo 3px), so they are widths and never read as a ring color.\n      'ring-w': [{ ring: ['focus', 'halo'] }],\n      'ring-offset-w': [{ 'ring-offset': ['focus'] }],\n      'font-weight': [{ font: ['regular'] }],\n      // Type roles (`typography-ui`, `typography-detail`, ...) set a whole font shorthand. The later role wins, so a className override is not swallowed by the component's own role.\n      typography: [{ typography: [() => true] }],\n    },\n  },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n\n// First letters of the first two words of a name, upper case (\"Ada Lovelace\" gives \"AL\"). Empty for an empty name.\nexport function getInitials(name: string, max = 2) {\n  return name\n    .split(/\\s+/)\n    .filter(Boolean)\n    .slice(0, max)\n    .map((part) => part.charAt(0).toUpperCase())\n    .join('');\n}\n",
      "type": "registry:lib"
    }
  ],
  "type": "registry:lib"
}