{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "gpuix-tw",
  "type": "registry:lib",
  "title": "Runtime: tw",
  "description": "The `@gpuixui/tw` modules the component items import. Installed automatically with the component; not a component itself.",
  "author": "Cyberistic <https://github.com/Cyberistic>",
  "dependencies": [
    "@gpuix/native@0.11.0",
    "@gpuix/react@0.11.0",
    "cn@^0.5.0",
    "effect@4.1.2"
  ],
  "registryDependencies": [
    "https://gpuixui.sudokw.com/gpuix-tokens.json"
  ],
  "files": [
    {
      "path": "packages/tw/src/aliases.ts",
      "target": "@ui/gpuixui/tw/aliases.ts",
      "type": "registry:lib",
      "content": "export const BASE_ALIASES: Readonly<Record<string, string>> = {\n  \"cn-input\":\n    \"bg-input/50 border-transparent focus-visible:border-ring focus-visible:ring-ring/30 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-9 rounded-3xl border px-3 py-1 text-base transition-[color,box-shadow,background-color] file:h-7 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm\",\n  \"cn-textarea\":\n    \"bg-input/50 border-transparent focus-visible:border-ring focus-visible:ring-ring/30 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 resize-none rounded-2xl border px-3 py-3 text-base transition-[color,box-shadow,background-color] focus-visible:ring-3 aria-invalid:ring-3 md:text-sm\",\n  \"cn-button\":\n    \"focus-visible:border-ring focus-visible:ring-ring/30 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-4xl border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 active:not-aria-[haspopup]:translate-y-px [&_svg:not([class*='size-'])]:size-4\",\n  \"cn-button-variant-default\":\n    \"bg-primary text-primary-foreground hover:bg-primary/80\",\n  \"cn-button-variant-outline\":\n    \"border-border bg-background dark:bg-transparent hover:bg-muted hover:text-foreground dark:hover:bg-input/30 aria-expanded:bg-muted aria-expanded:text-foreground\",\n  \"cn-button-variant-secondary\":\n    \"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n  \"cn-button-variant-ghost\":\n    \"hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground\",\n  \"cn-button-variant-destructive\":\n    \"bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30\",\n  \"cn-button-variant-link\": \"text-primary underline-offset-4 hover:underline\",\n  \"cn-button-size-xs\":\n    \"h-6 gap-1 px-2.5 text-xs has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3\",\n  \"cn-button-size-sm\":\n    \"h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n  \"cn-button-size-default\":\n    \"h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5\",\n  \"cn-button-size-lg\":\n    \"h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3\",\n  \"cn-button-size-icon-xs\": \"size-6 [&_svg:not([class*='size-'])]:size-3\",\n  \"cn-button-size-icon-sm\": \"size-8\",\n  \"cn-button-size-icon\": \"size-9\",\n  \"cn-button-size-icon-lg\": \"size-10\",\n  \"cn-dialog-overlay\":\n    \"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/30 duration-100 supports-backdrop-filter:backdrop-blur-sm\",\n  \"cn-dialog-content\":\n    \"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/5 dark:ring-foreground/10 grid max-w-[calc(100%-2rem)] gap-6 rounded-4xl p-6 text-sm shadow-xl ring-1 duration-100 sm:max-w-md\",\n  \"cn-dialog-close\": \"absolute top-4 right-4 bg-secondary\",\n  \"cn-dialog-header\": \"gap-1.5\",\n  \"cn-dialog-footer\": \"gap-2\",\n  \"cn-dialog-title\": \"text-base leading-none font-medium\",\n  \"cn-dialog-description\":\n    \"text-muted-foreground *:[a]:hover:text-foreground text-sm *:[a]:underline *:[a]:underline-offset-3\",\n  \"cn-popover-content\":\n    \"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 dark:ring-foreground/10 flex flex-col gap-4 rounded-3xl p-4 text-sm shadow-lg ring-1 duration-100\",\n  \"cn-popover-content-logical\":\n    \"data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2\",\n  \"cn-popover-header\": \"flex flex-col gap-1 text-sm\",\n  \"cn-popover-title\": \"text-base font-medium\",\n  \"cn-popover-description\": \"text-muted-foreground\",\n  \"cn-toast\": \"rounded-2xl\",\n  \"cn-skeleton\": \"bg-muted rounded-2xl\",\n};\n"
    },
    {
      "path": "packages/tw/src/calc.ts",
      "target": "@ui/gpuixui/tw/calc.ts",
      "type": "registry:lib",
      "content": "import { Data } from \"effect\";\nimport type { Theme } from \"../tokens/index.js\";\n\nexport type CalcResult = Data.TaggedEnum<{\n  Resolved: { readonly value: number };\n  Rejected: { readonly reason: string };\n}>;\n\nexport const CalcResult = Data.taggedEnum<CalcResult>();\n\nexport const CALC_REASONS = {\n  percentage: \"calc() cannot express a percentage\",\n  unit: \"calc() must resolve to a unitless number\",\n  function: \"calc() does not support min()/max()/clamp()\",\n  unknownFunction: \"calc() does not support this function\",\n  unknownToken: \"calc() references an unknown theme token\",\n  syntax: \"calc() could not be parsed\",\n} as const;\n\nconst TOKEN_PREFIXES = [\n  \"icon-size\",\n  \"spacing\",\n  \"radius\",\n  \"border-width\",\n  \"control-height\",\n  \"control-padding\",\n] as const;\n\nconst scaleAt = (scale: object, key: string): number | undefined =>\n  Object.hasOwn(scale, key)\n    ? (scale as Readonly<Record<string, number>>)[key]\n    : undefined;\n\nexport const themeTokenNumber = (\n  theme: Theme,\n  name: string,\n): number | undefined => {\n  const step = (prefix: string): string | undefined =>\n    name.startsWith(`${prefix}-`) ? name.slice(prefix.length + 1) : undefined;\n\n  const icon = step(\"icon-size\");\n  if (icon !== undefined) return scaleAt(theme.iconSize, icon);\n  const spacing = step(\"spacing\");\n  if (spacing !== undefined) return scaleAt(theme.spacing, spacing);\n  const radius = step(\"radius\");\n  if (radius !== undefined) return scaleAt(theme.radius, radius);\n  const border = step(\"border-width\");\n  if (border !== undefined) return scaleAt(theme.borderWidth, border);\n  const height = step(\"control-height\");\n  if (height !== undefined) return scaleAt(theme.density.controlHeight, height);\n  const padding = step(\"control-padding\");\n  if (padding !== undefined)\n    return scaleAt(theme.density.controlPaddingX, padding);\n  return name === \"row-height\" ? theme.density.rowHeight : undefined;\n};\n\nexport const isThemeTokenName = (name: string): boolean =>\n  name === \"row-height\" ||\n  TOKEN_PREFIXES.some((prefix) => name.startsWith(`${prefix}-`));\n\nconst calcInner = (expression: string): string | undefined => {\n  const trimmed = expression.trim();\n  return trimmed.startsWith(\"calc(\") && trimmed.endsWith(\")\")\n    ? trimmed.slice(\"calc(\".length, trimmed.length - 1)\n    : undefined;\n};\n\nconst isDigit = (character: string): boolean =>\n  character >= \"0\" && character <= \"9\";\nconst isLetter = (character: string): boolean =>\n  (character >= \"a\" && character <= \"z\") ||\n  (character >= \"A\" && character <= \"Z\");\nconst isSpace = (character: string): boolean =>\n  character === \" \" || character === \"\\t\" || character === \"\\n\";\n\ntype ResolveToken = (name: string) => number | undefined;\n\nconst { Resolved, Rejected } = CalcResult;\n\nconst run = (expression: string, resolveToken: ResolveToken): CalcResult => {\n  const inner = calcInner(expression);\n  if (inner === undefined) return Rejected({ reason: CALC_REASONS.syntax });\n\n  const source = inner;\n  const cursor = { value: 0 };\n\n  const skip = (): void => {\n    while (\n      cursor.value < source.length &&\n      isSpace(source.charAt(cursor.value))\n    ) {\n      cursor.value += 1;\n    }\n  };\n  const peek = (): string =>\n    cursor.value < source.length ? source.charAt(cursor.value) : \"\";\n\n  const number = (): number => {\n    const start = cursor.value;\n    while (\n      cursor.value < source.length &&\n      isDigit(source.charAt(cursor.value))\n    ) {\n      cursor.value += 1;\n    }\n    if (peek() === \".\") {\n      cursor.value += 1;\n      while (\n        cursor.value < source.length &&\n        isDigit(source.charAt(cursor.value))\n      ) {\n        cursor.value += 1;\n      }\n    }\n    return Number(source.slice(start, cursor.value));\n  };\n\n  const atom = (): CalcResult => {\n    skip();\n    const character = peek();\n    if (character === \"(\") {\n      cursor.value += 1;\n      const value = expr();\n      if (CalcResult.$is(\"Rejected\")(value)) return value;\n      skip();\n      if (peek() !== \")\") return Rejected({ reason: CALC_REASONS.syntax });\n      cursor.value += 1;\n      return value;\n    }\n    if (isDigit(character)) {\n      const value = number();\n      if (peek() === \"%\") return Rejected({ reason: CALC_REASONS.percentage });\n      if (isLetter(peek())) return Rejected({ reason: CALC_REASONS.unit });\n      return Resolved({ value });\n    }\n    if (isLetter(character)) {\n      const start = cursor.value;\n      while (\n        cursor.value < source.length &&\n        isLetter(source.charAt(cursor.value))\n      ) {\n        cursor.value += 1;\n      }\n      const name = source.slice(start, cursor.value);\n      skip();\n      if (peek() !== \"(\") return Rejected({ reason: CALC_REASONS.syntax });\n      cursor.value += 1;\n      if (name !== \"var\") {\n        return Rejected({\n          reason:\n            name === \"min\" || name === \"max\" || name === \"clamp\"\n              ? CALC_REASONS.function\n              : CALC_REASONS.unknownFunction,\n        });\n      }\n      skip();\n      if (!source.startsWith(\"--\", cursor.value))\n        return Rejected({ reason: CALC_REASONS.syntax });\n      cursor.value += 2;\n      const tokenStart = cursor.value;\n      while (\n        cursor.value < source.length &&\n        source.charAt(cursor.value) !== \")\" &&\n        !isSpace(source.charAt(cursor.value))\n      ) {\n        cursor.value += 1;\n      }\n      const token = source.slice(tokenStart, cursor.value);\n      skip();\n      if (peek() !== \")\") return Rejected({ reason: CALC_REASONS.syntax });\n      cursor.value += 1;\n      const value = resolveToken(token);\n      return value === undefined\n        ? Rejected({ reason: CALC_REASONS.unknownToken })\n        : Resolved({ value });\n    }\n    return Rejected({ reason: CALC_REASONS.syntax });\n  };\n\n  const unary = (): CalcResult => {\n    skip();\n    if (peek() === \"-\") {\n      cursor.value += 1;\n      return CalcResult.$match(unary(), {\n        Resolved: ({ value }) => Resolved({ value: -value }),\n        Rejected: (rejected) => rejected,\n      });\n    }\n    return atom();\n  };\n\n  const term = (): CalcResult => {\n    let left = unary();\n    while (CalcResult.$is(\"Resolved\")(left)) {\n      skip();\n      const operator = peek();\n      if (operator !== \"*\" && operator !== \"/\") return left;\n      cursor.value += 1;\n      const right = unary();\n      if (CalcResult.$is(\"Rejected\")(right)) return right;\n      left = Resolved({\n        value:\n          operator === \"*\"\n            ? left.value * right.value\n            : left.value / right.value,\n      });\n    }\n    return left;\n  };\n\n  const expr = (): CalcResult => {\n    let left = term();\n    while (CalcResult.$is(\"Resolved\")(left)) {\n      skip();\n      const operator = peek();\n      if (operator !== \"+\" && operator !== \"-\") return left;\n      cursor.value += 1;\n      const right = term();\n      if (CalcResult.$is(\"Rejected\")(right)) return right;\n      left = Resolved({\n        value:\n          operator === \"+\"\n            ? left.value + right.value\n            : left.value - right.value,\n      });\n    }\n    return left;\n  };\n\n  const result = expr();\n  if (CalcResult.$is(\"Rejected\")(result)) return result;\n  skip();\n  return cursor.value === source.length\n    ? result\n    : Rejected({ reason: CALC_REASONS.syntax });\n};\n\nexport const evaluateCalc = (expression: string, theme: Theme): CalcResult =>\n  run(expression, (name) => themeTokenNumber(theme, name));\n\nexport const calcReason = (expression: string): string | undefined =>\n  CalcResult.$match(\n    run(expression, (name) => (isThemeTokenName(name) ? 0 : undefined)),\n    {\n      Resolved: () => undefined,\n      Rejected: ({ reason }) => reason,\n    },\n  );\n\nexport const calcExpressions = (source: string): ReadonlyArray<string> => {\n  const results: Array<string> = [];\n  let index = 0;\n  while (index < source.length) {\n    const start = source.indexOf(\"calc(\", index);\n    if (start === -1) break;\n    let depth = 1;\n    let end = start + \"calc(\".length;\n    for (; end < source.length; end += 1) {\n      if (source.charAt(end) === \"(\") depth += 1;\n      else if (source.charAt(end) === \")\") {\n        depth -= 1;\n        if (depth === 0) break;\n      }\n    }\n    results.push(source.slice(start, end + 1));\n    index = end + 1;\n  }\n  return results;\n};\n\nexport const calcReasonFromClass = (className: string): string | undefined => {\n  for (const expression of calcExpressions(className)) {\n    const reason = calcReason(expression);\n    if (reason !== undefined) return reason;\n  }\n  return undefined;\n};\n"
    },
    {
      "path": "packages/tw/src/classes.ts",
      "target": "@ui/gpuixui/tw/classes.ts",
      "type": "registry:lib",
      "content": "import { cn } from \"cn\";\nimport { Match, pipe } from \"effect\";\nimport * as Arr from \"effect/Array\";\nimport * as Option from \"effect/Option\";\nimport * as Str from \"effect/String\";\nimport type { StyleDesc } from \"@gpuix/react\";\nimport type { Theme } from \"../tokens/index.js\";\nimport {\n  createTwRegistry,\n  defaultRegistry,\n  registryAlias,\n  registryReason,\n  resolveRegistryUtility,\n  type TwBucket,\n  type TwRegistry,\n  type TwRegistryConfig,\n  type TwState,\n} from \"./registry.js\";\nimport { prefixReason } from \"./unsupported.js\";\nimport { isRing, ringColor, ringShadow, ringWidth } from \"./utilities.js\";\nimport { calcReasonFromClass } from \"./calc.js\";\n\nexport type { TwBucket, TwState } from \"./registry.js\";\n\ntype Bucket = TwBucket | \"base\" | \"hover\" | \"active\";\n\nexport interface TwResult {\n  readonly style: StyleDesc;\n  readonly focus: StyleDesc;\n  readonly invalid: StyleDesc;\n  readonly disabled: StyleDesc;\n  readonly open: StyleDesc;\n  readonly closed: StyleDesc;\n\n  readonly motion: ReadonlyArray<string>;\n\n  readonly responsive: ReadonlyArray<string>;\n\n  readonly unsupported: ReadonlyArray<string>;\n}\n\ntype StateStyle = NonNullable<StyleDesc[\"hover\"]>;\n\ninterface Ring {\n  readonly width?: number;\n  readonly color?: string;\n}\n\ninterface Pass {\n  readonly result: TwResult;\n  readonly rings: Map<Bucket, Ring>;\n}\n\ninterface Split {\n  readonly variants: ReadonlyArray<string>;\n  readonly utility: string;\n}\n\ninterface SplitState {\n  readonly depth: number;\n  readonly start: number;\n  readonly variants: ReadonlyArray<string>;\n}\n\nconst empty = (): TwResult => ({\n  style: {},\n  focus: {},\n  invalid: {},\n  disabled: {},\n  open: {},\n  closed: {},\n  motion: [],\n  responsive: [],\n  unsupported: [],\n});\n\nexport const mergeTwStyle = (base: StyleDesc, next: StyleDesc): StyleDesc => {\n  const hover =\n    base.hover === undefined && next.hover === undefined\n      ? undefined\n      : { ...base.hover, ...next.hover };\n  const active =\n    base.active === undefined && next.active === undefined\n      ? undefined\n      : { ...base.active, ...next.active };\n  return {\n    ...base,\n    ...next,\n    ...(hover === undefined ? {} : { hover }),\n    ...(active === undefined ? {} : { active }),\n  };\n};\n\nconst state = (base: StateStyle | undefined, next: StyleDesc): StateStyle => ({\n  ...base,\n  ...next,\n});\n\nconst splitVariants = (token: string): Split => {\n  const initial: SplitState = { depth: 0, start: 0, variants: [] };\n  const split = Arr.reduce(\n    Str.split(token, \"\"),\n    initial,\n    (current, character, index) => {\n      if (character === \"[\" || character === \"(\") {\n        return { ...current, depth: current.depth + 1 };\n      }\n      if (character === \"]\" || character === \")\") {\n        return { ...current, depth: current.depth - 1 };\n      }\n      if (character === \":\" && current.depth === 0) {\n        return {\n          ...current,\n          variants: Arr.append(\n            current.variants,\n            Str.slice(current.start, index)(token),\n          ),\n          start: index + 1,\n        };\n      }\n      return current;\n    },\n  );\n  return {\n    variants: split.variants,\n    utility: Str.slice(split.start, token.length)(token),\n  };\n};\n\nconst RESPONSIVE = new Set([\"sm\", \"md\", \"lg\", \"xl\", \"2xl\"]);\nconst MOTION = /^(animate-|fade-|zoom-|slide-|duration-|ease-)/;\nconst UNSUPPORTED_VARIANT = new Set([\n  \"selection\",\n  \"file\",\n  \"placeholder\",\n  \"supports-backdrop-filter\",\n  \"group\",\n  \"peer\",\n  \"*\",\n]);\n\nconst stateVariant = (variant: string, state: TwState): boolean | undefined =>\n  Match.value(variant).pipe(\n    Match.when(\"has-[>svg]\", () => state.hasIcon === true),\n    Match.when(\n      \"has-data-[icon=inline-start]\",\n      () => state.iconSide === \"start\",\n    ),\n    Match.when(\"has-data-[icon=inline-end]\", () => state.iconSide === \"end\"),\n    Match.when(\"data-expanded\", () => state.expanded === true),\n    Match.when(\"aria-expanded\", () => state.expanded === true),\n    Match.when(\"data-behind\", () => state.behind === true),\n    Match.when(\"data-limited\", () => state.limited === true),\n    Match.orElse(() => undefined),\n  );\n\nconst bucketOf = (\n  variants: ReadonlyArray<string>,\n  registry: TwRegistry,\n  state: TwState,\n): Bucket | \"skip\" | \"unsupported\" => {\n  const custom = Arr.reduce(\n    registry.variants,\n    Option.none<TwBucket>(),\n    (found, resolve) =>\n      Option.isSome(found)\n        ? found\n        : Option.fromNullishOr(resolve(variants, state)),\n  );\n  if (Option.isSome(custom)) return custom.value;\n\n  if (Arr.some(variants, (variant) => variant === \"dark\")) return \"skip\";\n  if (\n    Arr.some(\n      variants,\n      (variant) =>\n        UNSUPPORTED_VARIANT.has(variant) || Str.startsWith(\"[&\")(variant),\n    )\n  ) {\n    return \"unsupported\";\n  }\n  return Option.match(Arr.last(variants), {\n    onNone: () => \"base\",\n    onSome: (last) => {\n      const matched = stateVariant(last, state);\n      if (matched !== undefined) return matched ? \"base\" : \"skip\";\n      if (last === \"focus\" || last === \"focus-visible\") return \"focus\";\n      if (last === \"aria-invalid\") return \"invalid\";\n      if (last === \"disabled\") return \"disabled\";\n      if (last === \"hover\") return \"hover\";\n      if (last === \"active\") return \"active\";\n      if (last === \"data-open\" || last === \"data-[state=open]\") return \"open\";\n      if (last === \"data-closed\" || last === \"data-[state=closed]\") {\n        return \"closed\";\n      }\n      if (Str.startsWith(\"data-[side=\")(last)) return \"base\";\n      if (RESPONSIVE.has(last)) return \"base\";\n      return \"unsupported\";\n    },\n  });\n};\n\nconst expandAliases = (className: string, registry: TwRegistry): string =>\n  pipe(\n    Str.split(className, /\\s+/),\n    Arr.filter(Str.isNonEmpty),\n    Arr.flatMap((token) => {\n      const { variants, utility } = splitVariants(token);\n      return Option.match(registryAlias(registry, utility), {\n        onNone: () => [token],\n        onSome: (recipe) =>\n          pipe(\n            Str.split(recipe, /\\s+/),\n            Arr.filter(Str.isNonEmpty),\n            Arr.map((part) =>\n              Arr.length(variants) === 0\n                ? part\n                : `${Arr.join(variants, \":\")}:${part}`,\n            ),\n          ),\n      });\n    }),\n    Arr.join(\" \"),\n  );\n\nconst ringOf = (utility: string, theme: Theme): Ring | undefined => {\n  if (!isRing(utility)) return undefined;\n  const width = ringWidth(utility);\n  const color = width === undefined ? ringColor(theme, utility) : undefined;\n  if (width === undefined && color === undefined) return undefined;\n  return {\n    ...(width === undefined ? {} : { width }),\n    ...(color === undefined ? {} : { color }),\n  };\n};\n\nconst setBucket = (\n  result: TwResult,\n  bucket: TwBucket,\n  next: StyleDesc,\n): TwResult =>\n  Match.value(bucket).pipe(\n    Match.when(\"focus\", () => ({\n      ...result,\n      focus: mergeTwStyle(result.focus, next),\n    })),\n    Match.when(\"invalid\", () => ({\n      ...result,\n      invalid: mergeTwStyle(result.invalid, next),\n    })),\n    Match.when(\"disabled\", () => ({\n      ...result,\n      disabled: mergeTwStyle(result.disabled, next),\n    })),\n    Match.when(\"open\", () => ({\n      ...result,\n      open: mergeTwStyle(result.open, next),\n    })),\n    Match.when(\"closed\", () => ({\n      ...result,\n      closed: mergeTwStyle(result.closed, next),\n    })),\n    Match.exhaustive,\n  );\n\nconst apply = (result: TwResult, bucket: Bucket, next: StyleDesc): TwResult =>\n  Match.value(bucket).pipe(\n    Match.when(\"base\", () => ({\n      ...result,\n      style: mergeTwStyle(result.style, next),\n    })),\n    Match.when(\"hover\", () => ({\n      ...result,\n      style: {\n        ...result.style,\n        hover: state(result.style.hover, next),\n      },\n    })),\n    Match.when(\"active\", () => ({\n      ...result,\n      style: {\n        ...result.style,\n        active: state(result.style.active, next),\n      },\n    })),\n    Match.orElse((value) => setBucket(result, value, next)),\n  );\n\nconst addRing = (\n  rings: Map<Bucket, Ring>,\n  bucket: Bucket,\n  ring: Ring,\n): Map<Bucket, Ring> => {\n  const current = rings.get(bucket) ?? {};\n  const next = new Map(rings);\n  next.set(bucket, {\n    width: ring.width ?? current.width,\n    color: ring.color ?? current.color,\n  });\n  return next;\n};\n\nexport const classesToStyle = (\n  className: string | undefined,\n  theme: Theme,\n  registry: TwRegistry = defaultRegistry,\n  state: TwState = {},\n): TwResult => {\n  const expanded = expandAliases(className ?? \"\", registry);\n  const tokens = Arr.filter(Str.split(cn(expanded), /\\s+/), Str.isNonEmpty);\n  const passed = Arr.reduce(\n    tokens,\n    {\n      result: empty(),\n      rings: new Map<Bucket, Ring>(),\n    } satisfies Pass,\n    (current, token) => {\n      const { variants, utility } = splitVariants(token);\n      if (Option.isSome(registryReason(registry, token))) {\n        return {\n          ...current,\n          result: {\n            ...current.result,\n            unsupported: Arr.append(current.result.unsupported, token),\n          },\n        };\n      }\n\n      const bucket = bucketOf(variants, registry, state);\n      if (bucket === \"skip\") return current;\n      if (bucket === \"unsupported\") {\n        return {\n          ...current,\n          result: {\n            ...current.result,\n            unsupported: Arr.append(current.result.unsupported, token),\n          },\n        };\n      }\n\n      const responsive = Arr.filter(variants, (variant) =>\n        RESPONSIVE.has(variant),\n      );\n      const result =\n        Arr.length(responsive) === 0\n          ? current.result\n          : {\n              ...current.result,\n              responsive: Arr.append(current.result.responsive, token),\n            };\n\n      if (MOTION.test(utility)) {\n        return {\n          ...current,\n          result: { ...result, motion: Arr.append(result.motion, token) },\n        };\n      }\n\n      const ring = ringOf(utility, theme);\n      if (ring !== undefined) {\n        return {\n          ...current,\n          result,\n          rings: addRing(current.rings, bucket, ring),\n        };\n      }\n\n      const resolved = resolveRegistryUtility(registry, utility, theme);\n      if (resolved === undefined) {\n        if (Arr.length(responsive) > 0) return { ...current, result };\n        return {\n          ...current,\n          result: {\n            ...result,\n            unsupported: Arr.append(result.unsupported, token),\n          },\n        };\n      }\n\n      return { ...current, result: apply(result, bucket, resolved) };\n    },\n  );\n\n  return Arr.reduce(\n    Arr.fromIterable(passed.rings),\n    passed.result,\n    (result, [bucket, ring]) =>\n      ring.width === undefined\n        ? result\n        : apply(result, bucket, ringShadow(theme, ring.width, ring.color)),\n  );\n};\n\nexport const unsupportedReason = (\n  className: string,\n  registry: TwRegistry = defaultRegistry,\n): string | undefined =>\n  Option.getOrUndefined(registryReason(registry, className)) ??\n  calcReasonFromClass(className) ??\n  prefixReason(className);\n\nexport interface TwCompiler {\n  readonly registry: TwRegistry;\n  readonly classesToStyle: (\n    className: string | undefined,\n    theme: Theme,\n    state?: TwState,\n  ) => TwResult;\n  readonly unsupportedReason: (className: string) => string | undefined;\n}\n\nexport const createTw = (config: TwRegistryConfig = {}): TwCompiler => {\n  const registry = createTwRegistry(config);\n  return {\n    registry,\n    classesToStyle: (className, theme, state) =>\n      classesToStyle(className, theme, registry, state),\n    unsupportedReason: (className) => unsupportedReason(className, registry),\n  };\n};\n"
    },
    {
      "path": "packages/tw/src/index.ts",
      "target": "@ui/gpuixui/tw/index.ts",
      "type": "registry:lib",
      "content": "export { cn } from \"cn\";\nexport {\n  classesToStyle,\n  createTw,\n  mergeTwStyle,\n  unsupportedReason,\n  type TwCompiler,\n  type TwResult,\n} from \"./classes.js\";\nexport {\n  createTwRegistry,\n  defaultRegistry,\n  type TwBucket,\n  type TwRegistry,\n  type TwRegistryConfig,\n  type TwState,\n  type TwUtilityResolver,\n  type TwVariantResolver,\n} from \"./registry.js\";\nexport { createRecipeCache } from \"./recipe-cache.js\";\nexport { BASE_ALIASES } from \"./aliases.js\";\nexport {\n  dialogMotion,\n  motionFromClasses,\n  overlayMotion,\n  toastMotion,\n  type TwMotion,\n} from \"./motion.js\";\nexport { resolveUtility, type Utility } from \"./utilities.js\";\nexport { unsupportedClasses } from \"./unsupported.js\";\nexport {\n  CALC_REASONS,\n  calcReason,\n  calcReasonFromClass,\n  calcExpressions,\n  evaluateCalc,\n  isThemeTokenName,\n  themeTokenNumber,\n  type CalcResult,\n} from \"./calc.js\";\nexport {\n  BUTTON_BASE,\n  BUTTON_SIZES,\n  BUTTON_VARIANTS,\n  DIALOG_CONTENT,\n  DIALOG_HEADER,\n  DIALOG_DESCRIPTION,\n  DIALOG_FOOTER,\n  DIALOG_OVERLAY,\n  DIALOG_TITLE,\n  INPUT_BASE,\n  INPUT_FOCUS,\n  INPUT_INVALID,\n  POPOVER_CONTENT,\n} from \"./recipes.js\";\nexport {\n  ALERT_BASE,\n  ALERT_CONTENT,\n  ALERT_DESCRIPTION,\n  ALERT_ICON,\n  ALERT_TITLE,\n  ALERT_TONES,\n  AVATAR_DISC,\n  AVATAR_FALLBACK,\n  AVATAR_ROOT,\n  BADGE_BASE,\n  BADGE_SIZES,\n  BADGE_VARIANTS,\n  CARD_BASE,\n  CARD_CONTENT,\n  CARD_DESCRIPTION,\n  CARD_FOOTER,\n  CARD_HEADER,\n  CARD_TITLE,\n  CARD_VARIANTS,\n  EMPTY_STATE_ACTION,\n  EMPTY_STATE_DESCRIPTION,\n  EMPTY_STATE_ICON,\n  EMPTY_STATE_ROOT,\n  EMPTY_STATE_TITLE,\n  LIST_ITEM,\n  LIST_ITEM_DESCRIPTION,\n  LIST_ITEM_TITLE,\n  LIST_ROOT,\n  PAGINATION_ELLIPSIS,\n  PAGINATION_LIST,\n  PAGINATION_ROOT,\n  STEPPER_DESCRIPTION,\n  STEPPER_LABEL,\n  STEPPER_MARKER,\n  STEPPER_MARKER_TEXT,\n  STEPPER_ORIENTATION,\n  STEPPER_ROOT,\n  STEPPER_STEP,\n  STEPPER_TEXT,\n  ACCORDION_ROOT,\n  ACCORDION_ITEM,\n  ACCORDION_TRIGGER,\n  ACCORDION_TRIGGER_ROW,\n  ACCORDION_INDICATOR,\n  ACCORDION_CONTENT,\n  BREADCRUMB_ROOT,\n  BREADCRUMB_LIST,\n  BREADCRUMB_ITEM,\n  BREADCRUMB_LINK,\n  BREADCRUMB_PAGE,\n  BREADCRUMB_SEPARATOR,\n  BREADCRUMB_ELLIPSIS,\n  CAROUSEL_INDICATORS,\n  CAROUSEL_ROOT,\n  CAROUSEL_TRACK,\n  CAROUSEL_SLIDE,\n  COLLAPSIBLE_ROOT,\n  COLLAPSIBLE_TRIGGER,\n  COLLAPSIBLE_CONTENT,\n  COUNTDOWN,\n  FIELD_ROOT,\n  FIELD_LABEL_ROW,\n  FIELD_LABEL,\n  FIELD_REQUIRED,\n  FIELD_DESCRIPTION,\n  FIELD_ERROR,\n  FIELD_INPUT,\n  FIELDSET_ROOT,\n  FIELDSET_LEGEND,\n  FORM_ROOT,\n  FORM_ERRORS,\n  FORM_ERROR,\n  HOTKEY_RECORDER,\n  HOTKEY_RECORDER_TEXT,\n  HOTKEY_RECORDER_KEYS,\n  HOTKEY_RECORDER_CLEAR,\n  INLINE_EDIT_DISPLAY,\n  INLINE_EDIT_DISPLAY_TEXT,\n  INLINE_EDIT_INPUT,\n  KEYBOARD_SHORTCUTS_ROOT,\n  KEYBOARD_SHORTCUTS_GROUP,\n  KEYBOARD_SHORTCUTS_HEADING,\n  KEYBOARD_SHORTCUTS_ROW,\n  KEYBOARD_SHORTCUTS_SEPARATOR,\n  KEYBOARD_SHORTCUT,\n  KEYBOARD_SHORTCUT_LABEL,\n  KEYBOARD_SHORTCUT_KEYS,\n  KEYCAP,\n  KEYCAP_TEXT,\n  MENTION_INPUT_FIELD,\n  MENTION_INPUT_CONTROL,\n  MENTION_INPUT_LIST,\n  MENTION_INPUT_ITEM,\n  MENTION_INPUT_ITEM_TEXT,\n  SEARCH_INPUT,\n  SEARCH_INPUT_ICON,\n  SEARCH_INPUT_CONTROL,\n  SEARCH_INPUT_CLEAR,\n  TAG_INPUT_ROOT,\n  TAG_INPUT_FIELD,\n  TAG_INPUT_CHIP,\n  TAG_INPUT_CHIP_TEXT,\n  TAG_INPUT_CHIP_REMOVE,\n  TAG_INPUT_HINT,\n  TAG_INPUT_CAPTION,\n  TIMELINE_ROOT,\n  TIMELINE_ITEM,\n  TIMELINE_RAIL,\n  TIMELINE_DOT,\n  TIMELINE_CONNECTOR,\n  TIMELINE_CONTENT,\n  TIMELINE_TIMESTAMP,\n  TIMELINE_TITLE,\n  TIMELINE_DESCRIPTION,\n  MENU_CONTENT,\n  MENU_ITEM,\n  MENU_LABEL,\n  MENU_SEPARATOR,\n  MENU_GROUP,\n  COMMAND_INPUT,\n  COMMAND_LIST,\n  COMMAND_EMPTY,\n  COMMAND_SHORTCUT,\n  COMMAND_HINT,\n  TOAST_VIEWPORT,\n  TOAST_STACK,\n  TOAST_CARD,\n  TOAST_BODY,\n  TOAST_DRAG,\n  TOAST_COPY,\n  TOAST_TITLE,\n  TOAST_DESCRIPTION,\n  TOAST_GLYPH,\n  TABS_ROOT,\n  TABS_ORIENTATION,\n  TABS_LIST,\n  TABS_LIST_ORIENTATION,\n  TABS_TRIGGER,\n  TABS_CONTENT,\n  PREVIEW_CARD_CONTENT,\n  CONFIRM_DIALOG_BUSY,\n  DRAWER_OVERLAY,\n  DRAWER_CONTENT,\n  DRAWER_HEADER,\n  DRAWER_TITLE,\n  DRAWER_DESCRIPTION,\n  DRAWER_FOOTER,\n  NAVIGATION_MENU_ROOT,\n  NAVIGATION_MENU_LIST,\n  NAVIGATION_MENU_ITEM,\n  NAVIGATION_MENU_CONTENT,\n  NAVIGATION_MENU_LINK,\n  COMBOBOX_TRIGGER,\n  COMBOBOX_TRIGGER_TEXT,\n  COMBOBOX_CARET,\n  COMBOBOX_CONTENT,\n  COMBOBOX_INPUT,\n  COMBOBOX_LIST,\n  COMBOBOX_ITEM,\n  COMBOBOX_ITEM_TEXT,\n  COMBOBOX_ITEM_DESCRIPTION,\n  COMBOBOX_ITEM_MARK,\n  COMBOBOX_EMPTY,\n  DATE_PICKER_TRIGGER,\n  DATE_PICKER_TRIGGER_TEXT,\n  DATE_PICKER_CARET,\n  DATE_PICKER_CONTENT,\n  CALENDAR_ROOT,\n  CALENDAR_MONTH,\n  CALENDAR_MONTH_LABEL,\n  CALENDAR_GRID,\n  CALENDAR_WEEKDAY,\n  CALENDAR_DAY,\n  TIME_PICKER_ROOT,\n  TIME_PICKER_SEGMENT,\n  TIME_PICKER_SEPARATOR,\n  TIME_PICKER_CLEAR,\n  COLOR_PICKER_TRIGGER,\n  COLOR_PICKER_PANEL,\n  COLOR_PICKER_ROW,\n  COLOR_PICKER_AREA,\n  COLOR_PICKER_SWATCHES,\n  COLOR_PICKER_FIELD,\n  COLOR_PICKER_INPUT,\n  COLOR_PICKER_CONTRAST,\n  COLOR_PICKER_CELL,\n  MESSAGE_SCROLLER_ROOT,\n  MESSAGE_SCROLLER_VIEWPORT,\n  MESSAGE_SCROLLER_CONTENT,\n  MESSAGE_SCROLLER_ITEM,\n  MESSAGE_SCROLLER_JUMP,\n  BUBBLE_ROOT,\n  BUBBLE_COLUMN,\n  BUBBLE_CONTENT,\n  BUBBLE_VARIANTS,\n  BUBBLE_ACTIONS,\n  BUBBLE_REACTIONS,\n  BUBBLE_GROUP,\n  MESSAGE_ROOT,\n  MESSAGE_CONTENT,\n  MESSAGE_HEADER,\n  MESSAGE_FOOTER,\n  MESSAGE_GROUP,\n  MESSAGE_AUTHOR,\n  MESSAGE_REASONING,\n  MESSAGE_REASONING_TRIGGER,\n  MESSAGE_REASONING_CONTENT,\n  MESSAGE_TOOL_CALL,\n  MESSAGE_TOOL_CALL_HEAD,\n  MESSAGE_TOOL_CALL_NAME,\n  MESSAGE_TOOL_CALL_STATUS,\n  MESSAGE_TOOL_CALL_RESULT,\n  MESSAGE_SOURCES,\n  MESSAGE_SOURCE,\n  MESSAGE_STREAMING,\n  MESSAGE_ACTIONS,\n  CHAT_ROOT,\n  CHAT_HEADER,\n  CHAT_HEADER_COPY,\n  CHAT_HEADER_TITLE,\n  CHAT_HEADER_STATUS,\n  CHAT_HEADER_ACTIONS,\n  CHAT_MESSAGES,\n  CHAT_EMPTY,\n  CHAT_EMPTY_TITLE,\n  CHAT_EMPTY_DESCRIPTION,\n  CHAT_COMPOSER,\n  CHAT_COMPOSER_ROW,\n  CHAT_COMPOSER_FIELD,\n  CHAT_COMPOSER_ATTACHMENTS,\n  CHAT_COMPOSER_HINT,\n  SIDEBAR_ROOT,\n  SIDEBAR_INNER,\n  SIDEBAR_FLOATING,\n  SIDEBAR_INSET,\n  SIDEBAR_HEADER,\n  SIDEBAR_CONTENT,\n  SIDEBAR_FOOTER,\n  SIDEBAR_SEPARATOR,\n  SIDEBAR_GROUP,\n  SIDEBAR_GROUP_LABEL,\n  SIDEBAR_GROUP_LABEL_TEXT,\n  SIDEBAR_GROUP_ACTION,\n  SIDEBAR_GROUP_CONTENT,\n  SIDEBAR_MENU,\n  SIDEBAR_MENU_ITEM,\n  SIDEBAR_MENU_BUTTON,\n  SIDEBAR_MENU_BUTTON_SIZES,\n  SIDEBAR_MENU_LABEL,\n  SIDEBAR_MENU_ACTION,\n  SIDEBAR_MENU_BADGE,\n  SIDEBAR_MENU_SKELETON,\n  SIDEBAR_MENU_SKELETON_ICON,\n  SIDEBAR_MENU_SKELETON_TEXT,\n  SIDEBAR_MENU_SUB,\n  SIDEBAR_MENU_SUB_ITEM,\n  SIDEBAR_MENU_SUB_BUTTON,\n  SIDEBAR_INPUT,\n  SIDEBAR_TOOLTIP,\n  SIDEBAR_TOOLTIP_TEXT,\n  SIDEBAR_SCRIM,\n  SIDEBAR_SHEET,\n  USER_MENU_TRIGGER,\n  USER_MENU_IDENTITY,\n  USER_MENU_NAME,\n  USER_MENU_EMAIL,\n  ASPECT_RATIO,\n  HOVER_CARD_CONTENT,\n  ITEM_GROUP,\n  ITEM_BASE,\n  ITEM_VARIANTS,\n  ITEM_SIZES,\n  ITEM_MEDIA,\n  ITEM_MEDIA_VARIANTS,\n  ITEM_CONTENT,\n  ITEM_TITLE,\n  ITEM_DESCRIPTION,\n  ITEM_ACTIONS,\n  ITEM_HEADER,\n  ITEM_FOOTER,\n  INPUT_GROUP,\n  INPUT_GROUP_ROW,\n  INPUT_GROUP_BLOCK,\n  INPUT_GROUP_FOCUS,\n  INPUT_GROUP_INVALID,\n  INPUT_GROUP_ADDONS,\n  INPUT_GROUP_TEXT,\n} from \"./recipes.js\";\n"
    },
    {
      "path": "packages/tw/src/motion.ts",
      "target": "@ui/gpuixui/tw/motion.ts",
      "type": "registry:lib",
      "content": "import { Match } from \"effect\";\nimport * as Arr from \"effect/Array\";\nimport * as Option from \"effect/Option\";\nimport * as Str from \"effect/String\";\nimport type { MotionProps, MotionStyle, MotionTransition } from \"@gpuix/react\";\nimport type { Theme } from \"../tokens/index.js\";\nimport { classesToStyle } from \"./classes.js\";\n\nexport interface TwMotion extends MotionProps {\n  readonly unsupported: ReadonlyArray<string>;\n}\n\nconst is = (token: string, value: string): boolean =>\n  token === value || Str.endsWith(value)(token);\n\nconst has = (tokens: ReadonlyArray<string>, value: string): boolean =>\n  Arr.some(tokens, (token) => is(token, value));\n\nconst durationOf = (tokens: ReadonlyArray<string>): number =>\n  Option.getOrElse(\n    Option.map(\n      Arr.findFirst(tokens, (token) => token.includes(\"duration-\")),\n      (token) => {\n        const value = Number(token.slice(token.lastIndexOf(\"duration-\") + 9));\n        return Number.isFinite(value) ? value / 1000 : 0.1;\n      },\n    ),\n    () => 0.1,\n  );\n\nconst slideOf = (\n  tokens: ReadonlyArray<string>,\n): { readonly top?: number; readonly left?: number } =>\n  Option.match(\n    Arr.findFirst(tokens, (token) => token.includes(\"slide-in-from-\")),\n    {\n      onNone: () => ({}),\n      onSome: (token) => {\n        const amount = Number(token.slice(token.lastIndexOf(\"-\") + 1)) * 4;\n        const offset = Number.isFinite(amount) ? amount : 8;\n        return Match.value(token).pipe(\n          Match.when(\n            (value) => value.includes(\"slide-in-from-top\"),\n            () => ({ top: -offset }),\n          ),\n          Match.when(\n            (value) => value.includes(\"slide-in-from-bottom\"),\n            () => ({ top: offset }),\n          ),\n          Match.when(\n            (value) => value.includes(\"slide-in-from-left\"),\n            () => ({ left: -offset }),\n          ),\n          Match.when(\n            (value) => value.includes(\"slide-in-from-right\"),\n            () => ({ left: offset }),\n          ),\n          Match.orElse(() => ({})),\n        );\n      },\n    },\n  );\n\nconst easeOf = (\n  tokens: ReadonlyArray<string>,\n): NonNullable<MotionTransition[\"ease\"]> =>\n  Option.match(\n    Arr.findFirst(tokens, (token) => token.includes(\"ease-\")),\n    {\n      onNone: () => \"easeOut\",\n      onSome: (token) => {\n        if (Str.startsWith(\"ease-[cubic-bezier(\")(token)) {\n          const body = token.slice(\"ease-[cubic-bezier(\".length, -2);\n          const values = Str.split(body, \",\").map((value) => Number(value));\n          const [a, b, c, d] = values;\n          if (\n            values.length === 4 &&\n            a !== undefined &&\n            b !== undefined &&\n            c !== undefined &&\n            d !== undefined &&\n            values.every((value) => Number.isFinite(value))\n          ) {\n            return [a, b, c, d];\n          }\n        }\n        if (token.includes(\"ease-in-out\")) return \"easeInOut\";\n        if (token.includes(\"ease-in\")) return \"easeIn\";\n        if (token.includes(\"ease-out\")) return \"easeOut\";\n        if (token.includes(\"ease-linear\")) return \"linear\";\n        return \"easeOut\";\n      },\n    },\n  );\n\nexport const motionFromClasses = (\n  className: string | undefined,\n  theme: Theme,\n): TwMotion => {\n  const parsed = classesToStyle(className, theme);\n  const tokens = parsed.motion;\n  const slide = slideOf(tokens);\n  const duration = durationOf(tokens);\n  const fadeIn = has(tokens, \"fade-in-0\");\n  const fadeOut = has(tokens, \"fade-out-0\");\n  const animateIn = has(tokens, \"animate-in\");\n  const animateOut = has(tokens, \"animate-out\");\n  const initial: MotionStyle = {\n    ...(fadeIn ? { opacity: 0 } : {}),\n    ...slide,\n  };\n  const animate: MotionStyle = {\n    ...(fadeIn ? { opacity: 1 } : {}),\n    ...(slide.top === undefined ? {} : { top: 0 }),\n    ...(slide.left === undefined ? {} : { left: 0 }),\n  };\n  const exit: MotionStyle | undefined =\n    fadeOut || animateOut\n      ? {\n          ...(fadeOut ? { opacity: 0 } : {}),\n          ...slide,\n        }\n      : undefined;\n  return {\n    ...(animateIn ? { initial } : {}),\n    animate: animateIn ? animate : {},\n    ...(exit === undefined ? {} : { exit }),\n    transition: { duration, ease: easeOf(tokens) },\n    unsupported: Arr.filter(tokens, (token) => token.includes(\"zoom-\")),\n  };\n};\n\nexport const dialogMotion = (theme: Theme): TwMotion =>\n  motionFromClasses(\n    \"data-open:animate-in data-closed:animate-out data-open:fade-in-0 data-closed:fade-out-0 duration-100\",\n    theme,\n  );\n\nexport const overlayMotion = (theme: Theme): TwMotion =>\n  motionFromClasses(\n    \"data-open:animate-in data-closed:animate-out data-open:fade-in-0 data-closed:fade-out-0 duration-100\",\n    theme,\n  );\n\nexport const toastMotion = (theme: Theme): TwMotion =>\n  motionFromClasses(\n    \"data-open:animate-in data-closed:animate-out data-open:fade-in-0 data-closed:fade-out-0 duration-500 ease-[cubic-bezier(0.22,1,0.36,1)]\",\n    theme,\n  );\n"
    },
    {
      "path": "packages/tw/src/recipe-cache.ts",
      "target": "@ui/gpuixui/tw/recipe-cache.ts",
      "type": "registry:lib",
      "content": "import type { StyleDesc } from \"@gpuix/react\";\nimport type { Theme } from \"../tokens/index.js\";\nimport * as MutableHashMap from \"effect/MutableHashMap\";\nimport * as Option from \"effect/Option\";\nimport { classesToStyle } from \"./classes.js\";\n\nexport const createRecipeCache = (\n  limit: number,\n): ((recipe: string, theme: Theme) => StyleDesc) => {\n  const compiled = new WeakMap<\n    Theme,\n    MutableHashMap.MutableHashMap<string, StyleDesc>\n  >();\n\n  return (recipe, theme) => {\n    const byRecipe = compiled.get(theme);\n    if (byRecipe !== undefined) {\n      const hit = MutableHashMap.get(byRecipe, recipe);\n      if (Option.isSome(hit)) return hit.value;\n    }\n\n    const style = Object.freeze(classesToStyle(recipe, theme).style);\n    if (byRecipe === undefined) {\n      compiled.set(theme, MutableHashMap.make([recipe, style]));\n    } else if (MutableHashMap.size(byRecipe) < limit) {\n      MutableHashMap.set(byRecipe, recipe, style);\n    }\n    return style;\n  };\n};\n"
    },
    {
      "path": "packages/tw/src/recipes.ts",
      "target": "@ui/gpuixui/tw/recipes.ts",
      "type": "registry:lib",
      "content": "export const INPUT_BASE =\n  \"h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30\";\n\nexport const INPUT_FOCUS =\n  \"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\";\n\nexport const INPUT_INVALID =\n  \"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40\";\n\nexport const BUTTON_BASE =\n  \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const BUTTON_SIZES = {\n  default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n  xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n  sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n  lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n  icon: \"size-9\",\n  \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n  \"icon-sm\": \"size-8\",\n  \"icon-lg\": \"size-10\",\n} as const;\n\nexport const BUTTON_VARIANTS = {\n  default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n  destructive:\n    \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n  outline:\n    \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n  secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n  ghost: \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n  link: \"text-primary underline-offset-4 hover:underline\",\n} as const;\n\nexport const DIALOG_OVERLAY =\n  \"fixed inset-0 isolate z-50 data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-overlay duration-100 supports-backdrop-filter:backdrop-blur-sm\";\n\nexport const DIALOG_CONTENT =\n  \"fixed top-1/2 left-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 outline-none bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/5 dark:ring-foreground/10 grid max-w-[calc(100%-2rem)] gap-6 rounded-4xl p-6 text-sm shadow-xl ring-1 duration-100 sm:max-w-md\";\n\nexport const POPOVER_CONTENT =\n  \"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 dark:ring-foreground/10 flex flex-col gap-4 rounded-3xl p-4 text-sm shadow-lg ring-1 duration-100\";\n\nexport const CARD_BASE = \"flex flex-col overflow-hidden rounded-lg bg-card\";\nexport const CARD_VARIANTS = {\n  outline: \"border border-input\",\n  elevated: \"shadow-sm\",\n  plain: \"\",\n} as const;\nexport const CARD_HEADER = \"flex flex-col gap-1 px-4 pt-4 pb-3\";\nexport const CARD_TITLE = \"text-base font-semibold font-sans text-foreground\";\nexport const CARD_DESCRIPTION = \"text-sm font-sans text-muted-foreground\";\nexport const CARD_CONTENT = \"flex flex-col gap-3 px-4\";\nexport const CARD_FOOTER =\n  \"flex flex-row items-center justify-end gap-2 px-4 pt-3 pb-4 border-t border-input\";\n\nexport const BADGE_BASE =\n  \"flex flex-row items-center self-start rounded-full px-2 pt-0.5 pb-0.5 whitespace-nowrap\";\nexport const BADGE_SIZES = {\n  sm: \"text-xs font-sans\",\n  md: \"text-sm font-medium font-sans\",\n} as const;\nexport const BADGE_VARIANTS = {\n  neutral: \"bg-muted text-muted-foreground\",\n  primary: \"bg-primary text-primary-foreground\",\n  success: \"bg-successSoft text-successSoftForeground border border-success/30\",\n  warning: \"bg-warningSoft text-warningSoftForeground border border-warning/30\",\n  danger:\n    \"bg-destructiveSoft text-destructiveSoftForeground border border-destructive/30\",\n  info: \"bg-infoSoft text-infoSoftForeground border border-info/30\",\n  outline: \"text-muted-foreground border border-strong\",\n} as const;\n\nexport const ALERT_BASE =\n  \"flex flex-row items-start gap-3 p-3 rounded-md border\";\nexport const ALERT_TONES = {\n  info: \"bg-infoSoft text-infoSoftForeground border-info/30\",\n  success: \"bg-successSoft text-successSoftForeground border-success/30\",\n  warning: \"bg-warningSoft text-warningSoftForeground border-warning/30\",\n  danger:\n    \"bg-destructiveSoft text-destructiveSoftForeground border-destructive/30\",\n} as const;\nexport const ALERT_ICON = \"flex flex-row items-center shrink-0\";\nexport const ALERT_CONTENT = \"flex flex-col gap-0.5 flex-grow\";\nexport const ALERT_TITLE = \"text-sm font-semibold font-sans\";\nexport const ALERT_DESCRIPTION = \"text-sm font-sans text-foreground\";\n\nexport const AVATAR_ROOT =\n  \"relative flex flex-row items-center justify-center shrink-0\";\nexport const AVATAR_DISC =\n  \"flex flex-row items-center justify-center w-full h-full rounded-full overflow-hidden bg-muted\";\nexport const AVATAR_FALLBACK = \"text-sm font-medium font-sans text-foreground\";\n\nexport const LIST_ROOT = \"flex flex-col gap-0.5\";\nexport const LIST_ITEM =\n  \"flex flex-row items-center gap-3 pl-3 pr-3 rounded-sm\";\nexport const LIST_ITEM_TITLE = \"text-sm font-sans text-foreground\";\nexport const LIST_ITEM_DESCRIPTION =\n  \"text-xs font-sans text-muted-foreground text-ellipsis whitespace-nowrap\";\n\nexport const PAGINATION_ROOT = \"flex flex-row items-center gap-1\";\nexport const PAGINATION_LIST = \"flex flex-row items-center gap-1\";\nexport const PAGINATION_ELLIPSIS =\n  \"text-xs font-sans text-muted-foreground pl-0.5 pr-0.5\";\n\nexport const EMPTY_STATE_ROOT =\n  \"flex flex-col items-center justify-center gap-3 p-8\";\nexport const EMPTY_STATE_ICON =\n  \"flex flex-row items-center text-muted-foreground\";\nexport const EMPTY_STATE_TITLE =\n  \"text-sm font-semibold font-sans text-foreground text-center\";\nexport const EMPTY_STATE_DESCRIPTION =\n  \"text-sm font-sans text-muted-foreground text-center\";\nexport const EMPTY_STATE_ACTION = \"flex flex-row\";\n\nexport const STEPPER_ROOT = \"flex gap-6\";\nexport const STEPPER_ORIENTATION = {\n  horizontal: \"flex-row items-start\",\n  vertical: \"flex-col items-stretch\",\n} as const;\nexport const STEPPER_STEP = \"flex flex-row items-center gap-2\";\nexport const STEPPER_MARKER =\n  \"flex flex-row items-center justify-center rounded-full\";\nexport const STEPPER_MARKER_TEXT = \"text-xs font-sans\";\nexport const STEPPER_LABEL = \"text-sm font-medium font-sans\";\nexport const STEPPER_DESCRIPTION = \"text-xs font-sans text-muted-foreground\";\nexport const STEPPER_TEXT = \"flex flex-col gap-0.5\";\n\nexport const ACCORDION_ROOT = \"flex flex-col w-full\";\nexport const ACCORDION_ITEM = \"flex flex-col\";\nexport const ACCORDION_TRIGGER =\n  \"flex flex-row items-center justify-between gap-2 px-1 w-full text-sm font-medium font-sans text-foreground\";\nexport const ACCORDION_TRIGGER_ROW =\n  \"flex flex-row items-center flex-grow min-w-0\";\nexport const ACCORDION_INDICATOR = \"text-xs font-sans text-muted-foreground\";\nexport const ACCORDION_CONTENT =\n  \"flex flex-col gap-2 px-1 pb-2 text-muted-foreground\";\n\nexport const BREADCRUMB_ROOT = \"flex flex-row items-center\";\nexport const BREADCRUMB_LIST = \"flex flex-row items-center flex-wrap gap-1\";\nexport const BREADCRUMB_ITEM = \"flex flex-row items-center gap-1\";\nexport const BREADCRUMB_LINK =\n  \"text-xs font-sans text-muted-foreground cursor-pointer px-0.5 rounded-sm\";\nexport const BREADCRUMB_PAGE = \"text-xs font-sans text-foreground\";\nexport const BREADCRUMB_SEPARATOR =\n  \"text-xs font-sans text-muted-foreground select-none\";\nexport const BREADCRUMB_ELLIPSIS = \"text-xs font-sans text-muted-foreground\";\n\nexport const CAROUSEL_ROOT = \"flex flex-col gap-2\";\nexport const CAROUSEL_INDICATORS =\n  \"flex flex-row items-center justify-center gap-1\";\nexport const CAROUSEL_TRACK =\n  \"flex flex-row overflow-hidden rounded-lg border border-input bg-card\";\nexport const CAROUSEL_SLIDE = \"flex flex-col flex-grow\";\n\nexport const COLLAPSIBLE_ROOT = \"flex flex-col gap-0.5\";\nexport const COLLAPSIBLE_TRIGGER =\n  \"flex flex-row items-center justify-between gap-2 px-2 py-1.5 rounded-sm text-sm font-medium font-sans text-foreground cursor-pointer\";\nexport const COLLAPSIBLE_CONTENT =\n  \"flex flex-col gap-2 px-2 pt-1.5 pb-2 text-muted-foreground\";\n\nexport const COUNTDOWN = \"text-xs font-sans\";\n\nexport const FIELD_ROOT = \"flex flex-col gap-1\";\nexport const FIELD_LABEL_ROW = \"flex flex-row gap-0.5\";\nexport const FIELD_LABEL = \"text-sm font-medium font-sans text-foreground\";\nexport const FIELD_REQUIRED = \"text-sm font-medium font-sans text-destructive\";\nexport const FIELD_DESCRIPTION = \"text-xs font-sans text-muted-foreground\";\nexport const FIELD_ERROR = \"text-xs font-sans text-destructive\";\nexport const FIELD_INPUT = \"text-sm font-sans w-full px-2 rounded-md border\";\n\nexport const FIELDSET_ROOT =\n  \"flex flex-col gap-3 rounded-lg border border-input bg-card p-4\";\nexport const FIELDSET_LEGEND = \"text-sm font-medium font-sans\";\n\nexport const FORM_ROOT = \"flex flex-col gap-3\";\nexport const FORM_ERRORS = \"flex flex-col gap-0.5\";\nexport const FORM_ERROR = \"text-xs font-sans text-destructive\";\n\nexport const HOTKEY_RECORDER =\n  \"flex flex-row items-center justify-between gap-2 px-2 bg-background rounded-md border border-input\";\nexport const HOTKEY_RECORDER_TEXT = \"text-sm font-sans text-muted-foreground\";\nexport const HOTKEY_RECORDER_KEYS = \"flex flex-row items-center gap-1\";\nexport const HOTKEY_RECORDER_CLEAR =\n  \"text-xs font-sans flex items-center justify-center size-4 rounded-sm text-muted-foreground\";\n\nexport const INLINE_EDIT_DISPLAY =\n  \"flex flex-row items-center self-start px-1 rounded-sm\";\nexport const INLINE_EDIT_DISPLAY_TEXT = \"text-sm font-medium font-sans\";\nexport const INLINE_EDIT_INPUT =\n  \"text-sm font-sans px-1.5 bg-background text-input-foreground rounded-sm border border-input\";\n\nexport const KEYBOARD_SHORTCUTS_ROOT = \"flex flex-col gap-4\";\nexport const KEYBOARD_SHORTCUTS_GROUP = \"flex flex-col gap-0.5\";\nexport const KEYBOARD_SHORTCUTS_HEADING =\n  \"text-xs font-sans text-muted-foreground\";\nexport const KEYBOARD_SHORTCUTS_ROW = \"flex flex-col gap-0.5\";\nexport const KEYBOARD_SHORTCUTS_SEPARATOR = \"h-px bg-border\";\nexport const KEYBOARD_SHORTCUT =\n  \"flex flex-row items-center justify-between gap-3 py-1.5\";\nexport const KEYBOARD_SHORTCUT_LABEL =\n  \"text-sm font-medium font-sans text-foreground\";\nexport const KEYBOARD_SHORTCUT_KEYS = \"flex flex-row items-center gap-1\";\nexport const KEYCAP =\n  \"flex flex-row items-center justify-center min-w-5 h-5 px-1.5 bg-muted rounded-sm border border-input\";\nexport const KEYCAP_TEXT = \"text-xs font-sans text-muted-foreground\";\n\nexport const MENTION_INPUT_FIELD =\n  \"flex flex-row items-center px-2 bg-background rounded-md border border-input\";\nexport const MENTION_INPUT_CONTROL =\n  \"text-sm font-sans flex-grow h-full text-input-foreground\";\nexport const MENTION_INPUT_LIST =\n  \"flex flex-col min-w-[200px] p-1 bg-popover rounded-md border border-input pointer-events-auto\";\nexport const MENTION_INPUT_ITEM =\n  \"flex flex-row items-center px-1.5 py-1 rounded-sm\";\nexport const MENTION_INPUT_ITEM_TEXT = \"text-sm font-sans\";\n\nexport const SEARCH_INPUT =\n  \"flex flex-row items-center gap-2 px-2 bg-background border border-input rounded-md\";\nexport const SEARCH_INPUT_ICON =\n  \"text-sm font-sans text-muted-foreground select-none\";\nexport const SEARCH_INPUT_CONTROL =\n  \"text-sm font-sans flex-grow h-full text-input-foreground\";\nexport const SEARCH_INPUT_CLEAR =\n  \"text-xs font-sans flex items-center justify-center size-[18px] rounded-sm text-muted-foreground cursor-pointer\";\n\nexport const TAG_INPUT_ROOT =\n  \"flex flex-row flex-wrap items-center gap-1 px-1.5 py-0.5 bg-background rounded-md border border-input\";\nexport const TAG_INPUT_FIELD =\n  \"text-sm font-sans flex-grow min-w-20 text-input-foreground\";\nexport const TAG_INPUT_CAPTION = \"text-xs font-sans text-muted-foreground\";\nexport const TAG_INPUT_HINT =\n  \"text-xs font-sans text-muted-foreground select-none\";\nexport const TAG_INPUT_CHIP =\n  \"flex flex-row items-center gap-1 py-0 pl-2 pr-0.5 bg-secondary rounded-sm\";\nexport const TAG_INPUT_CHIP_TEXT =\n  \"text-xs font-sans text-secondary-foreground\";\nexport const TAG_INPUT_CHIP_REMOVE =\n  \"text-xs font-sans flex items-center justify-center size-4 rounded-sm text-muted-foreground\";\n\nexport const TIMELINE_ROOT = \"flex flex-col gap-3\";\nexport const TIMELINE_ITEM = \"flex flex-row items-stretch self-stretch gap-2\";\nexport const TIMELINE_RAIL = \"flex flex-col items-center w-4\";\nexport const TIMELINE_DOT = \"size-2 rounded-full mt-1\";\nexport const TIMELINE_CONNECTOR = \"w-px flex-grow bg-border mt-0.5\";\nexport const TIMELINE_CONTENT = \"flex flex-col gap-0.5 flex-grow\";\nexport const TIMELINE_TIMESTAMP = \"text-xs font-sans text-muted-foreground\";\nexport const TIMELINE_TITLE = \"text-sm font-medium font-sans\";\nexport const TIMELINE_DESCRIPTION = \"text-sm font-sans text-muted-foreground\";\n\nexport const DIALOG_HEADER = \"flex flex-col gap-2\";\n\nexport const DIALOG_TITLE = \"text-base font-medium text-popover-foreground\";\n\nexport const DIALOG_DESCRIPTION = \"text-sm text-muted-foreground\";\n\nexport const DIALOG_FOOTER = \"flex flex-row items-center justify-end gap-2\";\n\nexport const MENU_CONTENT =\n  \"bg-popover text-popover-foreground min-w-48 rounded-3xl p-1.5 gap-0.5 shadow-lg ring-1 ring-foreground/5\";\n\nexport const MENU_ITEM =\n  \"flex flex-row items-center gap-2 rounded-2xl pl-1.5 pr-2 text-sm font-medium text-popover-foreground\";\n\nexport const MENU_LABEL =\n  \"text-muted-foreground px-3 py-2.5 text-xs select-none\";\n\nexport const MENU_SEPARATOR = \"bg-border/50 my-1.5 h-px\";\n\nexport const MENU_GROUP = \"flex flex-col gap-0.5\";\n\nexport const COMMAND_INPUT = \"w-full text-sm\";\n\nexport const COMMAND_LIST = \"flex flex-col gap-2\";\n\nexport const COMMAND_EMPTY = \"py-6 text-center text-sm text-muted-foreground\";\n\nexport const COMMAND_SHORTCUT = \"text-xs text-muted-foreground\";\n\nexport const COMMAND_HINT = \"text-xs text-muted-foreground\";\n\nexport const TOAST_VIEWPORT =\n  \"flex flex-col items-end w-[356px] pointer-events-none\";\n\nexport const TOAST_STACK = \"flex flex-col items-center w-full\";\n\nexport const TOAST_CARD =\n  \"w-full bg-popover text-popover-foreground border border-border rounded-xl shadow-md pointer-events-auto overflow-hidden\";\n\nexport const TOAST_BODY = \"flex flex-row items-start gap-2.5 px-4 py-3.5\";\n\nexport const TOAST_DRAG = \"flex flex-row items-start gap-2.5 flex-grow min-w-0\";\n\nexport const TOAST_COPY = \"flex flex-col gap-1 flex-grow min-w-0\";\n\nexport const TOAST_TITLE =\n  \"text-sm font-semibold font-sans text-popover-foreground\";\n\nexport const TOAST_DESCRIPTION = \"text-xs font-sans text-muted-foreground\";\n\nexport const TOAST_GLYPH = \"text-sm font-medium font-sans\";\n\nexport const TABS_ROOT = \"flex gap-2\";\n\nexport const TABS_ORIENTATION = {\n  horizontal: \"flex-col\",\n  vertical: \"flex-row\",\n} as const;\n\nexport const TABS_LIST =\n  \"flex items-stretch gap-1 p-1 bg-background border border-border rounded-md\";\n\nexport const TABS_LIST_ORIENTATION = {\n  horizontal: \"flex-row\",\n  vertical: \"flex-col\",\n} as const;\n\nexport const TABS_TRIGGER =\n  \"flex flex-row items-center justify-center px-3 rounded-sm text-sm font-medium font-sans\";\n\nexport const TABS_CONTENT = \"flex flex-col gap-2 text-foreground\";\n\nexport const PREVIEW_CARD_CONTENT =\n  \"bg-popover text-popover-foreground min-w-[240px] max-w-[360px] p-3 rounded-lg border border-border shadow-md text-sm font-sans pointer-events-auto\";\n\nexport const CONFIRM_DIALOG_BUSY = \"text-sm font-medium font-sans\";\n\nexport const DRAWER_OVERLAY = \"bg-overlay\";\n\nexport const DRAWER_CONTENT =\n  \"flex flex-col gap-3 p-6 bg-popover text-popover-foreground border border-border shadow-lg pointer-events-auto\";\n\nexport const DRAWER_HEADER = \"flex flex-col gap-1 pr-6\";\n\nexport const DRAWER_TITLE =\n  \"text-base font-semibold font-sans text-popover-foreground\";\n\nexport const DRAWER_DESCRIPTION = \"text-sm font-sans text-muted-foreground\";\n\nexport const DRAWER_FOOTER = \"flex flex-row items-center justify-end gap-2\";\n\nexport const NAVIGATION_MENU_ROOT = \"flex flex-row items-center\";\n\nexport const NAVIGATION_MENU_LIST = \"flex flex-row items-center gap-0.5\";\n\nexport const NAVIGATION_MENU_ITEM = \"flex flex-row relative\";\n\nexport const NAVIGATION_MENU_CONTENT =\n  \"flex flex-col gap-0.5 min-w-[220px] p-1.5 bg-popover text-popover-foreground rounded-lg border border-border shadow-md pointer-events-auto\";\n\nexport const NAVIGATION_MENU_LINK =\n  \"flex flex-row items-center justify-start w-full p-1.5 rounded-sm\";\n\nexport const COMBOBOX_TRIGGER =\n  \"flex flex-row items-center justify-between gap-2 w-full px-2 bg-background border border-strong rounded-md text-sm font-medium font-sans\";\n\nexport const COMBOBOX_CONTENT =\n  \"flex flex-col gap-0.5 min-w-[220px] p-1 bg-popover text-popover-foreground rounded-md border border-border shadow-md pointer-events-auto\";\n\nexport const COMBOBOX_INPUT =\n  \"text-sm font-sans px-2 bg-input text-input-foreground rounded-sm border border-border\";\n\nexport const COMBOBOX_LIST = \"flex flex-col\";\n\nexport const COMBOBOX_ITEM =\n  \"flex flex-row items-center gap-2 px-2 py-1 rounded-sm text-sm font-sans\";\n\nexport const COMBOBOX_TRIGGER_TEXT = \"text-sm font-medium font-sans\";\n\nexport const COMBOBOX_CARET = \"text-xs font-sans text-muted-foreground\";\n\nexport const COMBOBOX_ITEM_TEXT = \"text-sm font-sans text-popover-foreground\";\n\nexport const COMBOBOX_ITEM_DESCRIPTION =\n  \"text-xs font-sans text-muted-foreground\";\n\nexport const COMBOBOX_ITEM_MARK = \"text-xs font-sans text-primary\";\n\nexport const COMBOBOX_EMPTY = \"text-sm font-sans text-muted-foreground py-3\";\n\nexport const DATE_PICKER_TRIGGER =\n  \"flex flex-row items-center justify-between gap-2 w-[220px] px-2 bg-background border border-strong rounded-md text-sm font-medium font-sans\";\n\nexport const DATE_PICKER_TRIGGER_TEXT = \"text-sm font-medium font-sans\";\n\nexport const DATE_PICKER_CARET = \"text-xs font-sans text-muted-foreground\";\n\nexport const DATE_PICKER_CONTENT =\n  \"flex flex-col gap-2 p-2 bg-popover text-popover-foreground rounded-md border border-border pointer-events-auto\";\n\nexport const CALENDAR_ROOT = \"flex flex-row items-start\";\n\nexport const CALENDAR_MONTH = \"flex flex-col gap-0.5\";\n\nexport const CALENDAR_MONTH_LABEL =\n  \"text-sm font-medium font-sans text-foreground\";\n\nexport const CALENDAR_GRID = \"flex flex-col gap-0.5\";\n\nexport const CALENDAR_WEEKDAY =\n  \"text-xs font-sans text-muted-foreground text-center\";\n\nexport const CALENDAR_DAY =\n  \"text-xs font-sans flex items-center justify-center rounded-sm\";\n\nexport const TIME_PICKER_ROOT =\n  \"flex flex-row items-center gap-0.5 px-1.5 bg-input border border-border rounded-md\";\n\nexport const TIME_PICKER_SEGMENT =\n  \"text-sm font-sans text-input-foreground text-center h-full p-0\";\n\nexport const TIME_PICKER_SEPARATOR =\n  \"text-sm font-sans text-muted-foreground select-none\";\n\nexport const TIME_PICKER_CLEAR =\n  \"text-xs font-sans flex items-center justify-center size-[18px] rounded-sm text-muted-foreground cursor-pointer\";\n\nexport const COLOR_PICKER_TRIGGER =\n  \"flex flex-row items-center gap-2.5 self-start rounded-full border border-border bg-background p-1.5 pr-4\";\n\nexport const COLOR_PICKER_PANEL = \"flex flex-col gap-3.5 p-3.5\";\n\nexport const COLOR_PICKER_ROW = \"flex flex-col gap-2\";\n\nexport const COLOR_PICKER_AREA = \"relative w-full rounded-xl\";\n\nexport const COLOR_PICKER_FIELD = \"flex flex-row items-center gap-2\";\n\nexport const COLOR_PICKER_INPUT = \"bg-background text-input-foreground\";\n\nexport const COLOR_PICKER_SWATCHES =\n  \"flex flex-row flex-wrap items-center gap-1.5\";\n\nexport const COLOR_PICKER_CONTRAST =\n  \"flex flex-row items-center gap-2.5 text-sm\";\n\nexport const COLOR_PICKER_CELL = \"rounded-full border border-border\";\n\nexport const MESSAGE_SCROLLER_ROOT = \"relative flex flex-col min-h-0 min-w-0\";\n\nexport const MESSAGE_SCROLLER_VIEWPORT =\n  \"flex flex-col min-h-0 min-w-0 bg-background text-foreground\";\n\nexport const MESSAGE_SCROLLER_CONTENT = \"flex flex-col min-w-0\";\n\nexport const MESSAGE_SCROLLER_ITEM =\n  \"flex flex-col min-w-0 shrink-0 self-stretch\";\n\nexport const MESSAGE_SCROLLER_JUMP =\n  \"flex flex-row items-center justify-center pointer-events-none\";\n\nexport const BUBBLE_ROOT = \"flex flex-row items-end gap-2 min-w-0\";\n\nexport const BUBBLE_COLUMN = \"flex flex-col gap-1 min-w-0\";\n\nexport const BUBBLE_CONTENT =\n  \"flex flex-col gap-1 rounded-xl px-3 py-2 text-sm min-w-0\";\n\nexport const BUBBLE_VARIANTS = {\n  default: \"bg-primary text-primary-foreground\",\n  secondary: \"bg-secondary text-secondary-foreground\",\n  muted: \"bg-muted text-foreground\",\n  tinted: \"bg-transparent text-foreground\",\n  outline: \"bg-background text-foreground border border-border\",\n  ghost: \"bg-transparent text-foreground\",\n  destructive: \"bg-destructiveSoft text-destructiveSoftForeground\",\n} as const;\n\nexport const BUBBLE_ACTIONS = \"flex flex-row items-center gap-1 min-h-0\";\n\nexport const BUBBLE_REACTIONS =\n  \"flex flex-row items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm\";\n\nexport const BUBBLE_GROUP = \"flex flex-col min-w-0\";\n\nexport const MESSAGE_ROOT = \"flex flex-row gap-3 self-stretch px-1\";\n\nexport const MESSAGE_CONTENT = \"flex flex-col gap-2 min-w-0 flex-grow\";\n\nexport const MESSAGE_HEADER =\n  \"flex flex-row items-center gap-2 min-w-0 text-xs font-medium font-sans text-muted-foreground\";\n\nexport const MESSAGE_FOOTER = \"flex flex-row items-center gap-2 min-w-0\";\n\nexport const MESSAGE_GROUP = \"flex flex-col min-w-0\";\n\nexport const MESSAGE_AUTHOR =\n  \"text-xs font-medium font-sans text-muted-foreground\";\n\nexport const MESSAGE_REASONING =\n  \"flex flex-col gap-1 rounded-md border border-border bg-card px-3 py-2\";\n\nexport const MESSAGE_REASONING_TRIGGER =\n  \"flex flex-row items-center justify-between gap-2 text-xs font-medium font-sans text-muted-foreground\";\n\nexport const MESSAGE_REASONING_CONTENT =\n  \"text-xs font-sans text-muted-foreground\";\n\nexport const MESSAGE_TOOL_CALL =\n  \"flex flex-col gap-1 rounded-md border border-border bg-card px-3 py-2\";\n\nexport const MESSAGE_TOOL_CALL_HEAD =\n  \"flex flex-row items-center justify-between gap-2\";\n\nexport const MESSAGE_TOOL_CALL_NAME =\n  \"text-xs font-medium font-sans text-foreground\";\n\nexport const MESSAGE_TOOL_CALL_STATUS =\n  \"flex flex-row items-center gap-1 text-xs font-sans text-muted-foreground\";\n\nexport const MESSAGE_TOOL_CALL_RESULT =\n  \"text-xs font-sans text-muted-foreground\";\n\nexport const MESSAGE_SOURCES = \"flex flex-col gap-1\";\n\nexport const MESSAGE_SOURCE =\n  \"flex flex-row items-center gap-1 text-xs font-sans text-muted-foreground\";\n\nexport const MESSAGE_STREAMING =\n  \"flex flex-row items-center gap-1.5 text-xs font-sans text-muted-foreground\";\n\nexport const MESSAGE_ACTIONS = \"flex flex-row items-center gap-1\";\n\nexport const CHAT_ROOT = \"flex flex-col gap-3 min-h-0 min-w-0 flex-grow\";\n\nexport const CHAT_HEADER =\n  \"flex flex-row items-start justify-between gap-3 shrink-0\";\n\nexport const CHAT_HEADER_COPY = \"flex flex-col gap-0.5 min-w-0 flex-grow\";\n\nexport const CHAT_HEADER_TITLE =\n  \"text-sm font-medium font-sans text-foreground\";\n\nexport const CHAT_HEADER_STATUS = \"text-xs font-sans text-muted-foreground\";\n\nexport const CHAT_HEADER_ACTIONS = \"flex flex-row items-center gap-1 shrink-0\";\n\nexport const CHAT_MESSAGES = \"flex flex-col min-h-0 min-w-0 flex-grow\";\n\nexport const CHAT_EMPTY =\n  \"flex flex-col items-center justify-center gap-1 py-8 text-center\";\n\nexport const CHAT_EMPTY_TITLE = \"text-sm font-medium font-sans text-foreground\";\n\nexport const CHAT_EMPTY_DESCRIPTION = \"text-xs font-sans text-muted-foreground\";\n\nexport const CHAT_COMPOSER =\n  \"flex flex-col gap-2 rounded-lg border border-border bg-background p-2\";\n\nexport const CHAT_COMPOSER_ROW = \"flex flex-row items-center gap-2\";\n\nexport const CHAT_COMPOSER_FIELD =\n  \"text-sm font-sans flex-grow px-2 py-1 bg-transparent text-input-foreground\";\n\nexport const CHAT_COMPOSER_ATTACHMENTS = \"flex flex-row flex-wrap gap-1.5\";\n\nexport const CHAT_COMPOSER_HINT = \"text-xs font-sans text-muted-foreground\";\n\nexport const SIDEBAR_ROOT = \"flex flex-row w-full h-full\";\n\nexport const SIDEBAR_INNER =\n  \"flex flex-col w-full h-full bg-card text-card-foreground\";\n\nexport const SIDEBAR_FLOATING = \"rounded-lg border border-border shadow-sm\";\n\nexport const SIDEBAR_INSET = \"flex flex-col flex-grow bg-background\";\n\nexport const SIDEBAR_HEADER = \"flex flex-col gap-2 p-2\";\n\nexport const SIDEBAR_CONTENT = \"flex flex-col flex-grow gap-0 min-h-0\";\n\nexport const SIDEBAR_FOOTER = \"flex flex-col gap-2 p-2\";\n\nexport const SIDEBAR_SEPARATOR = \"h-px bg-border mx-2\";\n\nexport const SIDEBAR_GROUP = \"flex flex-col w-full p-2 relative\";\n\nexport const SIDEBAR_GROUP_LABEL =\n  \"flex flex-row items-center gap-2 h-8 px-2 rounded-md overflow-hidden\";\n\nexport const SIDEBAR_GROUP_LABEL_TEXT =\n  \"text-xs font-medium font-sans text-muted-foreground\";\n\nexport const SIDEBAR_GROUP_ACTION =\n  \"flex flex-row items-center justify-center rounded-md text-card-foreground\";\n\nexport const SIDEBAR_GROUP_CONTENT = \"flex flex-col w-full text-sm\";\n\nexport const SIDEBAR_MENU = \"flex flex-col w-full gap-0.5\";\n\nexport const SIDEBAR_MENU_ITEM = \"relative\";\n\nexport const SIDEBAR_MENU_BUTTON =\n  \"flex flex-row items-center justify-start w-full gap-2 px-2 rounded-md text-sm text-left text-card-foreground overflow-hidden\";\n\nexport const SIDEBAR_MENU_BUTTON_SIZES = {\n  default: \"h-9\",\n  sm: \"h-8\",\n  lg: \"h-12\",\n} as const;\n\nexport const SIDEBAR_MENU_LABEL =\n  \"flex-grow text-sm font-sans whitespace-nowrap text-ellipsis overflow-hidden\";\n\nexport const SIDEBAR_MENU_ACTION =\n  \"flex flex-row items-center justify-center rounded-md text-card-foreground\";\n\nexport const SIDEBAR_MENU_BADGE =\n  \"flex flex-row items-center justify-center h-5 min-w-5 px-1 rounded-md text-xs font-medium font-sans text-muted-foreground\";\n\nexport const SIDEBAR_MENU_SKELETON =\n  \"flex flex-row items-center h-9 gap-2 px-2 rounded-md\";\n\nexport const SIDEBAR_MENU_SKELETON_ICON = \"size-4 rounded-md bg-muted\";\n\nexport const SIDEBAR_MENU_SKELETON_TEXT = \"h-4 rounded-md bg-muted flex-grow\";\n\nexport const SIDEBAR_MENU_SUB = \"flex flex-col min-w-0 gap-1 py-0.5\";\n\nexport const SIDEBAR_MENU_SUB_ITEM = \"relative\";\n\nexport const SIDEBAR_MENU_SUB_BUTTON =\n  \"flex flex-row items-center justify-start min-w-0 gap-2 px-2 rounded-md text-muted-foreground overflow-hidden\";\n\nexport const SIDEBAR_INPUT = \"w-full bg-background\";\n\nexport const SIDEBAR_TOOLTIP =\n  \"bg-popover text-popover-foreground rounded-md border border-border px-2 py-1 shadow-sm pointer-events-auto\";\n\nexport const SIDEBAR_TOOLTIP_TEXT =\n  \"text-xs font-sans text-popover-foreground whitespace-nowrap\";\n\nexport const SIDEBAR_SCRIM = \"bg-overlay\";\n\nexport const SIDEBAR_SHEET =\n  \"flex flex-col h-full bg-card text-card-foreground border-border shadow-lg\";\n\nexport const USER_MENU_TRIGGER =\n  \"flex flex-row items-center gap-2 px-2 rounded-md bg-transparent text-card-foreground\";\n\nexport const USER_MENU_IDENTITY = \"flex flex-col items-start min-w-0 flex-grow\";\n\nexport const USER_MENU_NAME =\n  \"min-w-0 overflow-hidden text-sm font-medium font-sans text-card-foreground whitespace-nowrap text-ellipsis\";\n\nexport const USER_MENU_EMAIL =\n  \"min-w-0 overflow-hidden text-xs font-sans text-muted-foreground whitespace-nowrap text-ellipsis\";\n\nexport const ASPECT_RATIO = \"relative w-full\";\n\nexport const HOVER_CARD_CONTENT =\n  \"bg-popover text-popover-foreground w-64 p-4 rounded-md border border-border shadow-md text-sm font-sans pointer-events-auto\";\n\nexport const ITEM_GROUP = \"flex flex-col w-full gap-2\";\n\nexport const ITEM_BASE = \"flex flex-row flex-wrap items-center w-full\";\n\nexport const ITEM_VARIANTS = {\n  default: \"\",\n  outline: \"border border-input rounded-md\",\n  muted: \"bg-muted rounded-md\",\n} as const;\n\nexport const ITEM_SIZES = {\n  default: \"gap-3 p-3\",\n  sm: \"gap-2 p-2\",\n} as const;\n\nexport const ITEM_MEDIA = \"flex flex-row items-center justify-center shrink-0\";\n\nexport const ITEM_MEDIA_VARIANTS = {\n  default: \"\",\n  icon: \"size-9 rounded-md bg-muted\",\n  image: \"size-10 rounded-md overflow-hidden\",\n} as const;\n\nexport const ITEM_CONTENT = \"flex flex-col flex-1 min-w-0 gap-1\";\n\nexport const ITEM_TITLE =\n  \"text-sm font-medium font-sans text-foreground whitespace-nowrap text-ellipsis overflow-hidden\";\n\nexport const ITEM_DESCRIPTION =\n  \"text-sm font-sans text-muted-foreground overflow-hidden\";\n\nexport const ITEM_ACTIONS = \"flex flex-row items-center gap-2\";\n\nexport const ITEM_HEADER =\n  \"flex flex-row items-center justify-between w-full gap-2\";\n\nexport const ITEM_FOOTER =\n  \"flex flex-row items-center justify-between w-full gap-2\";\n\nexport const INPUT_GROUP =\n  \"flex flex-col w-full min-w-0 rounded-md border border-input bg-transparent\";\n\nexport const INPUT_GROUP_ROW = \"flex flex-row items-center w-full min-w-0\";\n\nexport const INPUT_GROUP_BLOCK = \"flex flex-row items-center w-full min-w-0\";\n\nexport const INPUT_GROUP_FOCUS = \"border-ring ring-[3px] ring-ring/50\";\n\nexport const INPUT_GROUP_INVALID =\n  \"border-destructive ring-[3px] ring-destructive/20\";\n\nexport const INPUT_GROUP_ADDONS = {\n  \"inline-start\": \"flex flex-row items-center shrink-0 pl-3 gap-2\",\n  \"inline-end\": \"flex flex-row items-center shrink-0 pr-3 gap-2\",\n  \"block-start\":\n    \"flex flex-row items-center justify-start w-full shrink-0 px-3 pt-2 gap-2\",\n  \"block-end\":\n    \"flex flex-row items-center justify-start w-full shrink-0 px-3 pb-2 gap-2\",\n} as const;\n\nexport const INPUT_GROUP_TEXT =\n  \"flex flex-row items-center text-sm font-sans text-muted-foreground whitespace-nowrap\";\n"
    },
    {
      "path": "packages/tw/src/registry.ts",
      "target": "@ui/gpuixui/tw/registry.ts",
      "type": "registry:lib",
      "content": "import { Order, pipe } from \"effect\";\nimport * as Arr from \"effect/Array\";\nimport * as Option from \"effect/Option\";\nimport * as P from \"effect/Predicate\";\nimport * as R from \"effect/Record\";\nimport * as Str from \"effect/String\";\nimport type { StyleDesc } from \"@gpuix/react\";\nimport type { Theme } from \"../tokens/index.js\";\nimport { BASE_ALIASES } from \"./aliases.js\";\nimport { unsupportedReasons } from \"./unsupported.js\";\nimport { resolveUtility } from \"./utilities.js\";\n\nexport type TwBucket = \"focus\" | \"invalid\" | \"disabled\" | \"open\" | \"closed\";\n\nexport interface TwState {\n  readonly hasIcon?: boolean;\n\n  readonly iconSide?: \"start\" | \"end\";\n\n  readonly expanded?: boolean;\n\n  readonly behind?: boolean;\n\n  readonly limited?: boolean;\n}\n\nexport type TwUtilityResolver = (\n  theme: Theme,\n  value?: string,\n) => StyleDesc | number | undefined;\n\nexport type TwVariantResolver = (\n  variants: ReadonlyArray<string>,\n  state: TwState,\n) => TwBucket | undefined;\n\nexport interface TwRegistryConfig {\n  readonly utilities?: Readonly<Record<string, TwUtilityResolver>>;\n  readonly variants?: ReadonlyArray<TwVariantResolver>;\n  readonly aliases?: Readonly<Record<string, string>>;\n  readonly unsupported?: Readonly<Record<string, string>>;\n}\n\nexport interface TwRegistry {\n  readonly utilities: Readonly<Record<string, TwUtilityResolver>>;\n  readonly variants: ReadonlyArray<TwVariantResolver>;\n  readonly aliases: Readonly<Record<string, string>>;\n  readonly unsupported: Readonly<Record<string, string>>;\n}\n\nconst DEFAULTS: TwRegistry = {\n  utilities: {},\n  variants: [],\n  aliases: BASE_ALIASES,\n  unsupported: unsupportedReasons,\n};\n\nexport const defaultRegistry: TwRegistry = DEFAULTS;\n\nexport const createTwRegistry = (\n  config: TwRegistryConfig = {},\n): TwRegistry => ({\n  utilities: R.union(\n    DEFAULTS.utilities,\n    config.utilities ?? {},\n    (_default, next) => next,\n  ),\n  variants: Arr.appendAll(DEFAULTS.variants, config.variants ?? []),\n  aliases: R.union(\n    DEFAULTS.aliases,\n    config.aliases ?? {},\n    (_default, next) => next,\n  ),\n  unsupported: R.union(\n    DEFAULTS.unsupported,\n    config.unsupported ?? {},\n    (_default, next) => next,\n  ),\n});\n\nexport const registryAlias = (\n  registry: TwRegistry,\n  utility: string,\n): Option.Option<string> => R.get(registry.aliases, utility);\n\nexport const registryReason = (\n  registry: TwRegistry,\n  token: string,\n): Option.Option<string> => R.get(registry.unsupported, token);\n\nconst families = (\n  utilities: Readonly<Record<string, TwUtilityResolver>>,\n): ReadonlyArray<readonly [string, TwUtilityResolver]> =>\n  pipe(\n    R.toEntries(utilities),\n    Arr.sort(\n      Order.mapInput(\n        Order.Number,\n        (entry: readonly [string, TwUtilityResolver]) => -entry[0].length,\n      ),\n    ),\n  );\n\nconst asShape = (resolved: StyleDesc | number): StyleDesc =>\n  P.isNumber(resolved) ? { width: resolved, height: resolved } : resolved;\n\nexport const resolveRegistryUtility = (\n  registry: TwRegistry,\n  name: string,\n  theme: Theme,\n): StyleDesc | undefined => {\n  const exact = R.get(registry.utilities, name);\n  if (Option.isSome(exact)) {\n    const resolved = exact.value(theme);\n    if (resolved !== undefined) return asShape(resolved);\n  }\n\n  const family = Arr.findFirst(families(registry.utilities), ([key]) =>\n    Str.startsWith(`${key}-`)(name),\n  );\n  return Option.match(family, {\n    onNone: () => resolveUtility(name, theme),\n    onSome: ([key, resolve]) => {\n      const resolved = resolve(\n        theme,\n        Str.slice(key.length + 1, name.length)(name),\n      );\n      return resolved === undefined\n        ? resolveUtility(name, theme)\n        : asShape(resolved);\n    },\n  });\n};\n"
    },
    {
      "path": "packages/tw/src/unsupported.ts",
      "target": "@ui/gpuixui/tw/unsupported.ts",
      "type": "registry:lib",
      "content": "import * as Arr from \"effect/Array\";\nimport * as HashMap from \"effect/HashMap\";\nimport * as Option from \"effect/Option\";\nimport * as R from \"effect/Record\";\nimport * as Str from \"effect/String\";\n\nconst NO_TRANSFORM =\n  \"GPUix `StyleDesc` has no `transform` (no rotate/scale/translate/skew); \" +\n  \"animate motion with `@gpuixui/motion`, static transforms are unsupported.\";\nconst NO_GRID_SPAN =\n  \"GPUix grid has no span — only `gridColumnMin`/`gridRowMin` and integer \" +\n  \"`gridTemplateColumns`/`gridTemplateRows`; size the track or set an explicit width instead.\";\nconst NO_GRID_AREA =\n  \"GPUix grid has no named areas — only integer track counts; place the item \" +\n  \"with explicit row/column layout instead.\";\n\nconst GROUPS: ReadonlyArray<readonly [string, ReadonlyArray<string>]> = [\n  [\n    NO_TRANSFORM,\n    [\n      \"-translate-x-1/2\",\n      \"-translate-y-1/2\",\n      \"active:not-aria-[haspopup]:translate-y-px\",\n      \"origin-(--transform-origin)\",\n      \"origin-bottom\",\n      \"will-change-transform\",\n      \"[transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))]\",\n      \"data-starting-style:[transform:translateY(150%)]\",\n      \"data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]\",\n      \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(150%)]\",\n      \"data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n      \"data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n      \"data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n      \"data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n      \"data-expanded:data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n      \"data-expanded:data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n      \"data-expanded:data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n      \"data-expanded:data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n    ],\n  ],\n  [\n    \"GPUix has no CSS transitions; motion props animate explicit styles.\",\n    [\n      \"[transition:transform_500ms_cubic-bezier(0.22,1,0.36,1),opacity_500ms,height_150ms]\",\n      \"transition-[color,box-shadow,background-color]\",\n      \"transition-opacity\",\n    ],\n  ],\n  [\n    \"Pseudo-element rules have no native element to style.\",\n    [\n      \"after:-inset-2\",\n      \"after:absolute\",\n      \"after:content-['']\",\n      \"after:h-[calc(var(--gap)+1px)]\",\n      \"after:left-0\",\n      \"after:top-full\",\n      \"after:w-full\",\n      \"file:bg-transparent\",\n      \"file:border-0\",\n      \"file:font-medium\",\n      \"file:h-7\",\n      \"file:inline-flex\",\n      \"file:text-foreground\",\n      \"file:text-sm\",\n      \"placeholder:text-muted-foreground\",\n    ],\n  ],\n  [\n    \"Child and sibling selectors are not part of an element's own StyleDesc.\",\n    [\n      \"*:[a]:hover:text-foreground\",\n      \"*:[a]:underline\",\n      \"*:[a]:underline-offset-3\",\n      \"[&_svg]:pointer-events-none\",\n      \"[&_svg:not([class*='size-'])]:size-3\",\n      \"[&_svg:not([class*='size-'])]:size-4\",\n    ],\n  ],\n  [\n    \"Arbitrary CSS variables, calc() and color-mix() have no StyleDesc value.\",\n    [\n      \"[--gap:0.75rem]\",\n      \"[--height:var(--toast-frontmost-height,var(--toast-height))]\",\n      \"[--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))]\",\n      \"[--peek:0.75rem]\",\n      \"[--scale:calc(max(0,1-(var(--toast-index)*0.1)))]\",\n      \"[--shrink:calc(1-var(--scale))]\",\n      \"h-(--height)\",\n      \"data-expanded:h-(--toast-height)\",\n      \"max-w-[calc(100%-2rem)]\",\n      \"z-[calc(1000-var(--toast-index))]\",\n      \"hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]\",\n    ],\n  ],\n  [\n    \"GPUix StyleDesc has no background-clip, text-underline-offset or isolation.\",\n    [\"bg-clip-padding\", \"underline-offset-4\", \"isolate\"],\n  ],\n  [\n    \"GPUix draws rings as one box shadow; there is no separate ring offset.\",\n    [\"ring-offset-background\"],\n  ],\n  [\"Stacking order awaits the native zIndex slice.\", [\"z-50\"]],\n  [\n    \"`sr-only` needs clipping and a 1px box the native style cannot express.\",\n    [\"sr-only\"],\n  ],\n  [\"GPUix has no user-resize handle; the textarea is fixed.\", [\"resize-none\"]],\n  [\n    \"Percentage offsets and auto margins are not native numbers.\",\n    [\"top-1/2\", \"left-1/2\", \"mx-auto\"],\n  ],\n  [\n    \"GPUix has no backdrop filter.\",\n    [\"supports-backdrop-filter:backdrop-blur-sm\"],\n  ],\n  [\n    \"Registry apply-hook or group marker, not a Tailwind utility.\",\n    [\"cn-font-heading\", \"group/toast\"],\n  ],\n];\n\nconst PREFIX_GROUPS: ReadonlyArray<readonly [string, ReadonlyArray<string>]> = [\n  [NO_TRANSFORM, [\"transform\", \"rotate-\", \"scale-\", \"translate-\", \"skew-\"]],\n  [NO_GRID_SPAN, [\"col-span-\", \"row-span-\"]],\n  [NO_GRID_AREA, [\"grid-area-\"]],\n];\n\nconst BY_TOKEN = HashMap.fromIterable(\n  Arr.flatMap(GROUPS, ([reason, tokens]) =>\n    Arr.map(tokens, (token) => [token, reason] as const),\n  ),\n);\n\nexport const unsupportedClasses: ReadonlyArray<string> = Arr.flatMap(\n  GROUPS,\n  ([, tokens]) => tokens,\n);\n\nexport const unsupportedReasons: Readonly<Record<string, string>> =\n  R.fromEntries(\n    Arr.flatMap(GROUPS, ([reason, tokens]) =>\n      Arr.map(tokens, (token) => [token, reason] as const),\n    ),\n  );\n\nexport const prefixReason = (className: string): string | undefined =>\n  Option.match(\n    Arr.findFirst(PREFIX_GROUPS, ([, prefixes]) =>\n      Arr.some(prefixes, (prefix) => Str.startsWith(prefix)(className)),\n    ),\n    {\n      onNone: () => undefined,\n      onSome: ([reason]) => reason,\n    },\n  );\n\nexport const unsupportedReason = (className: string): string | undefined => {\n  const exact = HashMap.get(BY_TOKEN, className);\n  return Option.isSome(exact) ? exact.value : prefixReason(className);\n};\n"
    },
    {
      "path": "packages/tw/src/utilities.ts",
      "target": "@ui/gpuixui/tw/utilities.ts",
      "type": "registry:lib",
      "content": "import type { StyleDesc } from \"@gpuix/react\";\nimport {\n  alpha,\n  elevationShadow,\n  type ElevationLevel,\n  type Theme,\n  type ThemeColors,\n} from \"../tokens/index.js\";\nimport { CalcResult, evaluateCalc } from \"./calc.js\";\n\nexport type Utility = StyleDesc | ((theme: Theme) => StyleDesc);\n\nconst ROLE: Readonly<Record<string, keyof ThemeColors>> = {\n  background: \"background\",\n  foreground: \"foreground\",\n  card: \"card\",\n  \"card-foreground\": \"cardForeground\",\n  popover: \"popover\",\n  \"popover-foreground\": \"popoverForeground\",\n  primary: \"primary\",\n  \"primary-foreground\": \"primaryForeground\",\n  secondary: \"secondary\",\n  \"secondary-foreground\": \"secondaryForeground\",\n  muted: \"muted\",\n  \"muted-foreground\": \"mutedForeground\",\n  accent: \"accent\",\n  \"accent-foreground\": \"accentForeground\",\n  destructive: \"destructive\",\n  \"destructive-foreground\": \"destructiveForeground\",\n  success: \"success\",\n  \"success-foreground\": \"successForeground\",\n  warning: \"warning\",\n  \"warning-foreground\": \"warningForeground\",\n  info: \"info\",\n  \"info-foreground\": \"infoForeground\",\n  border: \"border\",\n  \"border-strong\": \"borderStrong\",\n  input: \"input\",\n  \"input-foreground\": \"inputForeground\",\n  ring: \"ring\",\n  overlay: \"overlay\",\n  hover: \"hover\",\n  active: \"active\",\n  selected: \"selected\",\n  \"selected-foreground\": \"selectedForeground\",\n  disabled: \"disabled\",\n  \"disabled-foreground\": \"disabledForeground\",\n  skeleton: \"skeleton\",\n  selection: \"selection\",\n  placeholder: \"placeholder\",\n\n  infoSoft: \"infoSoft\",\n  infoSoftForeground: \"infoSoftForeground\",\n  successSoft: \"successSoft\",\n  successSoftForeground: \"successSoftForeground\",\n  warningSoft: \"warningSoft\",\n  warningSoftForeground: \"warningSoftForeground\",\n  destructiveSoft: \"destructiveSoft\",\n  destructiveSoftForeground: \"destructiveSoftForeground\",\n};\n\nconst LITERAL: Readonly<Record<string, string>> = {\n  white: \"#FFFFFF\",\n  black: \"#000000\",\n  transparent: \"transparent\",\n};\n\nconst SPACING = (value: number): number => value * 4;\n\nconst CONTROL_HEIGHT: Readonly<Record<string, \"sm\" | \"md\" | \"lg\">> = {\n  \"8\": \"sm\",\n  \"9\": \"md\",\n  \"10\": \"lg\",\n};\n\nconst RADIUS: Readonly<Record<string, number>> = {\n  none: 0,\n  sm: 4,\n  md: 6,\n  lg: 8,\n  xl: 12,\n  \"2xl\": 16,\n  \"3xl\": 24,\n  \"4xl\": 32,\n  full: 9999,\n};\n\nconst MAX_WIDTH: Readonly<Record<string, number>> = {\n  sm: 384,\n  md: 448,\n};\n\nconst ELEVATION: Readonly<Record<string, ElevationLevel>> = {\n  xs: \"sm\",\n  sm: \"sm\",\n  md: \"md\",\n  lg: \"lg\",\n  xl: \"lg\",\n};\n\nconst TEXT_SIZE: Readonly<Record<string, readonly [number, number]>> = {\n  xs: [12, 16],\n  sm: [14, 20],\n  base: [16, 24],\n  lg: [18, 28],\n  xl: [20, 28],\n  \"2xl\": [24, 32],\n  \"3xl\": [30, 36],\n};\n\nconst FONT_WEIGHT: Readonly<Record<string, number>> = {\n  thin: 100,\n  light: 300,\n  normal: 400,\n  medium: 500,\n  semibold: 600,\n  bold: 700,\n};\n\nexport const colorRole = (theme: Theme, name: string): string | undefined => {\n  const role = ROLE[name];\n  return role === undefined ? undefined : theme.colors[role];\n};\n\nconst literal = (name: string): string | undefined => LITERAL[name];\n\nconst paint = (theme: Theme, value: string): string | undefined => {\n  const slash = value.indexOf(\"/\");\n  const name = slash === -1 ? value : value.slice(0, slash);\n  const rawAlpha = slash === -1 ? undefined : value.slice(slash + 1);\n  const color = literal(name) ?? colorRole(theme, name);\n  if (color === undefined) return undefined;\n  if (rawAlpha === undefined) return color;\n  const percent = Number(rawAlpha);\n  return Number.isFinite(percent) ? alpha(color, percent / 100) : undefined;\n};\n\nconst spacingValue = (value: string): number | undefined => {\n  if (value.startsWith(\"[\") && value.endsWith(\"px]\")) {\n    const px = Number(value.slice(1, -3));\n    return Number.isFinite(px) ? px : undefined;\n  }\n  const n = Number(value);\n  return Number.isFinite(n) ? SPACING(n) : undefined;\n};\n\nconst calcExpression = (value: string): string | undefined => {\n  if (value.startsWith(\"calc(\") && value.endsWith(\")\")) return value;\n  if (value.startsWith(\"[\") && value.endsWith(\"]\")) {\n    const inner = value.slice(1, -1);\n    return inner.startsWith(\"calc(\") && inner.endsWith(\")\") ? inner : undefined;\n  }\n  return undefined;\n};\n\nconst lengthValue = (value: string, theme: Theme): number | undefined => {\n  const calc = calcExpression(value);\n  if (calc !== undefined) {\n    return CalcResult.$match(evaluateCalc(calc, theme), {\n      Resolved: ({ value: number }) => number,\n      Rejected: () => undefined,\n    });\n  }\n  return spacingValue(value);\n};\n\nconst trackCount = (value: string): number | undefined => {\n  const n = Number(value);\n  return Number.isInteger(n) && n >= 1 ? n : undefined;\n};\n\nexport const resolveUtility = (\n  name: string,\n  theme: Theme,\n): StyleDesc | undefined => {\n  if (name === \"border\") return { borderWidth: 1 };\n\n  if (name === \"border-input\") return { borderColor: theme.colors.border };\n\n  if (name === \"border-strong\")\n    return { borderColor: theme.colors.borderStrong };\n  if (name === \"border-t\") return { borderTopWidth: 1 };\n  if (name === \"outline-none\" || name === \"outline-hidden\") return {};\n  if (name === \"bg-transparent\") return { backgroundColor: \"transparent\" };\n  if (name === \"flex\" || name === \"inline-flex\") return { display: \"flex\" };\n  if (name === \"grid\") return { display: \"grid\" };\n  if (name === \"flex-row\") return { flexDirection: \"row\" };\n  if (name === \"flex-col\") return { flexDirection: \"column\" };\n  if (name === \"flex-col-reverse\") return { flexDirection: \"column-reverse\" };\n  if (name === \"flex-1\") return { flexGrow: 1, flexShrink: 1, flexBasis: 0 };\n  if (name === \"flex-grow\") return { flexGrow: 1 };\n  if (name === \"flex-wrap\") return { flexWrap: \"wrap\" };\n  if (name === \"items-center\") return { alignItems: \"center\" };\n  if (name === \"items-start\") return { alignItems: \"flex-start\" };\n  if (name === \"items-end\") return { alignItems: \"flex-end\" };\n  if (name === \"items-stretch\") return { alignItems: \"stretch\" };\n  if (name === \"justify-center\") return { justifyContent: \"center\" };\n  if (name === \"justify-start\") return { justifyContent: \"flex-start\" };\n  if (name === \"justify-between\") return { justifyContent: \"space-between\" };\n  if (name === \"justify-end\") return { justifyContent: \"flex-end\" };\n  if (name === \"shrink-0\") return { flexShrink: 0 };\n  if (name === \"self-start\") return { alignSelf: \"flex-start\" };\n  if (name === \"self-stretch\") return { alignSelf: \"stretch\" };\n  if (name === \"w-full\") return { width: \"100%\" };\n  if (name === \"w-auto\") return { width: \"auto\" };\n  if (name === \"h-full\") return { height: \"100%\" };\n  if (name === \"min-w-0\") return { minWidth: 0 };\n  if (name === \"max-w-full\") return { maxWidth: \"100%\" };\n  if (name === \"overflow-hidden\") return { overflow: \"hidden\" };\n  if (name === \"leading-none\") return { lineHeight: 1 };\n  if (name === \"whitespace-nowrap\") return { whiteSpace: \"nowrap\" };\n  if (name === \"text-ellipsis\") return { textOverflow: \"ellipsis\" };\n  if (name === \"font-sans\") return { fontFamily: theme.typography.sans };\n  if (name === \"font-mono\") return { fontFamily: theme.typography.mono };\n  if (name === \"select-none\") return { userSelect: \"none\" };\n  if (name === \"pointer-events-none\") return { pointerEvents: \"none\" };\n  if (name === \"pointer-events-auto\") return { pointerEvents: \"auto\" };\n  if (name === \"cursor-pointer\") return { cursor: \"pointer\" };\n  if (name === \"cursor-not-allowed\") return { cursor: \"not-allowed\" };\n  if (name === \"absolute\") return { position: \"absolute\" };\n  if (name === \"relative\") return { position: \"relative\" };\n  if (name === \"fixed\") return { position: \"absolute\" };\n  if (name === \"inset-0\") return { top: 0, right: 0, bottom: 0, left: 0 };\n  if (name === \"text-left\") return { textAlign: \"left\" };\n  if (name === \"text-center\") return { textAlign: \"center\" };\n  if (name === \"text-right\") return { textAlign: \"right\" };\n  if (name === \"underline\") return { textDecoration: \"underline\" };\n  if (name === \"h-px\") return { height: 1 };\n  if (name === \"w-px\") return { width: 1 };\n\n  if (name.startsWith(\"h-\")) {\n    const control = CONTROL_HEIGHT[name.slice(2)];\n    if (control !== undefined) {\n      return { height: theme.density.controlHeight[control] };\n    }\n    const value = lengthValue(name.slice(2), theme);\n    return value === undefined ? undefined : { height: value };\n  }\n  if (name.startsWith(\"w-\")) {\n    const value = lengthValue(name.slice(2), theme);\n    return value === undefined ? undefined : { width: value };\n  }\n  if (name.startsWith(\"min-h-\")) {\n    const value = lengthValue(name.slice(6), theme);\n    return value === undefined ? undefined : { minHeight: value };\n  }\n  if (name.startsWith(\"min-w-\")) {\n    const value = lengthValue(name.slice(6), theme);\n    return value === undefined ? undefined : { minWidth: value };\n  }\n  if (name.startsWith(\"max-w-\")) {\n    const key = name.slice(6);\n    const named = MAX_WIDTH[key];\n    if (named !== undefined) return { maxWidth: named };\n    const value = lengthValue(key, theme);\n    return value === undefined ? undefined : { maxWidth: value };\n  }\n  if (name.startsWith(\"size-\")) {\n    const control = CONTROL_HEIGHT[name.slice(5)];\n    if (control !== undefined) {\n      const side = theme.density.controlHeight[control];\n      return { width: side, height: side };\n    }\n    const value = lengthValue(name.slice(5), theme);\n    return value === undefined ? undefined : { width: value, height: value };\n  }\n  if (name.startsWith(\"p-\")) {\n    const value = lengthValue(name.slice(2), theme);\n    return value === undefined ? undefined : { padding: value };\n  }\n  if (name.startsWith(\"px-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined\n      ? undefined\n      : { paddingLeft: value, paddingRight: value };\n  }\n  if (name.startsWith(\"py-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined\n      ? undefined\n      : { paddingTop: value, paddingBottom: value };\n  }\n  if (name.startsWith(\"pl-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined ? undefined : { paddingLeft: value };\n  }\n  if (name.startsWith(\"pr-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined ? undefined : { paddingRight: value };\n  }\n  if (name.startsWith(\"pt-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined ? undefined : { paddingTop: value };\n  }\n  if (name.startsWith(\"pb-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined ? undefined : { paddingBottom: value };\n  }\n  if (name.startsWith(\"mx-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined\n      ? undefined\n      : { marginLeft: value, marginRight: value };\n  }\n  if (name.startsWith(\"my-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined\n      ? undefined\n      : { marginTop: value, marginBottom: value };\n  }\n  if (name.startsWith(\"mt-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined ? undefined : { marginTop: value };\n  }\n  if (name.startsWith(\"mb-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined ? undefined : { marginBottom: value };\n  }\n  if (name.startsWith(\"ml-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined ? undefined : { marginLeft: value };\n  }\n  if (name.startsWith(\"mr-\")) {\n    const value = lengthValue(name.slice(3), theme);\n    return value === undefined ? undefined : { marginRight: value };\n  }\n  if (name.startsWith(\"inset-x-\")) {\n    const value = lengthValue(name.slice(8), theme);\n    return value === undefined ? undefined : { left: value, right: value };\n  }\n  if (name.startsWith(\"inset-y-\")) {\n    const value = lengthValue(name.slice(8), theme);\n    return value === undefined ? undefined : { top: value, bottom: value };\n  }\n  if (name.startsWith(\"top-\")) {\n    const value = lengthValue(name.slice(4), theme);\n    return value === undefined ? undefined : { top: value };\n  }\n  if (name.startsWith(\"right-\")) {\n    const value = lengthValue(name.slice(6), theme);\n    return value === undefined ? undefined : { right: value };\n  }\n  if (name.startsWith(\"bottom-\")) {\n    const value = lengthValue(name.slice(7), theme);\n    return value === undefined ? undefined : { bottom: value };\n  }\n  if (name.startsWith(\"left-\")) {\n    const value = lengthValue(name.slice(5), theme);\n    return value === undefined ? undefined : { left: value };\n  }\n  if (name.startsWith(\"grid-cols-\")) {\n    const count = trackCount(name.slice(10));\n    return count === undefined ? undefined : { gridTemplateColumns: count };\n  }\n  if (name.startsWith(\"grid-rows-\")) {\n    const count = trackCount(name.slice(10));\n    return count === undefined ? undefined : { gridTemplateRows: count };\n  }\n  if (name.startsWith(\"gap-x-\")) {\n    const value = lengthValue(name.slice(6), theme);\n    return value === undefined ? undefined : { columnGap: value };\n  }\n  if (name.startsWith(\"gap-y-\")) {\n    const value = lengthValue(name.slice(6), theme);\n    return value === undefined ? undefined : { rowGap: value };\n  }\n  if (name.startsWith(\"gap-\")) {\n    const value = lengthValue(name.slice(4), theme);\n    return value === undefined ? undefined : { gap: value };\n  }\n  if (name.startsWith(\"rounded-\")) {\n    const key = name.slice(8);\n    if (key === \"full\") return { borderRadius: 9999 };\n\n    const radius = theme.radius[key as keyof Theme[\"radius\"]] ?? RADIUS[key];\n    return radius === undefined ? undefined : { borderRadius: radius };\n  }\n  if (name.startsWith(\"text-\")) {\n    const size = TEXT_SIZE[name.slice(5)];\n    if (size !== undefined) {\n      return { fontSize: size[0], lineHeight: size[1] };\n    }\n    const color = paint(theme, name.slice(5));\n    return color === undefined ? undefined : { color };\n  }\n  if (name.startsWith(\"font-\")) {\n    const weight = FONT_WEIGHT[name.slice(5)];\n    return weight === undefined ? undefined : { fontWeight: weight };\n  }\n  if (name.startsWith(\"opacity-\")) {\n    const value = Number(name.slice(8));\n    return Number.isFinite(value) ? { opacity: value / 100 } : undefined;\n  }\n  if (name.startsWith(\"border-\")) {\n    const width = Number(name.slice(7));\n    if (Number.isFinite(width)) return { borderWidth: width };\n    const color = paint(theme, name.slice(7));\n    return color === undefined ? undefined : { borderColor: color };\n  }\n  if (name.startsWith(\"bg-\")) {\n    const color = paint(theme, name.slice(3));\n    return color === undefined ? undefined : { backgroundColor: color };\n  }\n  if (name.startsWith(\"shadow-\")) {\n    const elevation = ELEVATION[name.slice(7)];\n    return elevation === undefined\n      ? undefined\n      : { boxShadow: elevationShadow(theme, elevation) };\n  }\n  if (name === \"rounded\") return { borderRadius: RADIUS.sm };\n\n  return undefined;\n};\n\nexport const isRing = (name: string): boolean => name.startsWith(\"ring-\");\n\nexport const ringWidth = (name: string): number | undefined => {\n  if (!name.startsWith(\"ring-\")) return undefined;\n  const value = name.slice(5);\n  if (value.startsWith(\"[\")) return spacingValue(value);\n  const width = Number(value);\n  return value.length > 0 && Number.isFinite(width) ? width : undefined;\n};\n\nexport const ringColor = (theme: Theme, name: string): string | undefined =>\n  paint(theme, name.slice(5));\n\nexport const ringShadow = (\n  theme: Theme,\n  width: number,\n  color?: string,\n): StyleDesc => ({\n  boxShadow: {\n    offsetX: 0,\n    offsetY: 0,\n    blurRadius: 0,\n    spreadRadius: width,\n    color: color ?? theme.colors.ring,\n  },\n});\n"
    }
  ],
  "docs": "[Runtime: tw](https://gpuixui.sudokw.com/registry) — These are GPUix native components: the files render through GPUix's reconciler against `@gpuix/react`, not the DOM, and need the per-platform `@gpuix/native` binding. The CLI installs the `@gpuixui/*` runtime the components import as registry items, so the copied tree resolves on its own; wrap it in `ThemeProvider` before it renders.",
  "meta": {
    "url": "/registry",
    "kind": "runtime",
    "runtime": "gpuix",
    "registry": "gpuixui"
  }
}