{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "button-group-glass",
  "title": "Group-glass button",
  "description": "Styled button: the Group-glass set. 5 decorative button variations (FrostButtonGroup, TintButtonGroup, SmokeButtonGroup, CrystalButtonGroup, DepthButtonGroup) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [],
  "registryDependencies": [
    "@ai2/tokens",
    "@ai2/glass"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/button-group-glass.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\nimport { glassDepth } from \"@/registry/ai2/ui/glass\"\n\n/* Glass button-group family: five frosted action groups. The container is\n   translucent in every variant; the difference is in the blur step, the source of\n   the tint and the depth. Color comes ONLY from semantic tokens, via alpha\n   color-mix. Deterministic, no motion.\n\n   The surface derives from glassDepth in @ai2/glass (AGENTS.md 4.5).\n   This file differs from its siblings: here the glass sits on a CONTAINER rather\n   than a control (rounded-xl, p-1, a bar carrying three buttons edge to edge). So\n   there really is content behind it to diffuse and the scale can open upward:\n   sm..lg are used. xl is still absent - this is a bar, not a full-page overlay. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\n/* Base Button olcegiyle hizali: sm=h-8, md=h-9, lg=h-10, xl=h-12. */\nconst sizes: Record<StyledSize, string> = {\n  sm: \"h-8 px-3 text-sm\",\n  md: \"h-9 px-4 text-sm\",\n  lg: \"h-10 px-5 text-sm\",\n  xl: \"h-12 px-6 text-base\",\n}\n\ntype Action = {\n  label?: React.ReactNode\n  icon?: React.ReactNode\n  onClick?: () => void\n}\n\ntype GroupProps = {\n  className?: string\n  size?: StyledSize\n  actions?: Action[]\n}\n\nconst defaultActions: Action[] = [\n  { label: \"Left\" },\n  { label: \"Center\" },\n  { label: \"Right\" },\n]\n\nconst item =\n  \"relative inline-flex shrink-0 select-none items-center justify-center gap-2 rounded-md font-medium whitespace-nowrap outline-none transition-colors focus-visible:z-10 focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_i]:text-base [&_i]:leading-none\"\n\n/* Shared shell: a translucent container with the buttons floating inside it. */\nfunction GlassShell({\n  props,\n  label,\n  shellClassName,\n  itemClassName,\n}: {\n  props: GroupProps\n  label: string\n  shellClassName: string\n  itemClassName: string\n}) {\n  const { className, size = \"md\", actions = defaultActions } = props\n\n  return (\n    <div\n      data-slot=\"styled-button-group\"\n      role=\"group\"\n      aria-label={label}\n      className={cn(\n        \"inline-flex items-center gap-1 rounded-xl border p-1 isolate\",\n        shellClassName,\n        className\n      )}\n    >\n      {actions.map((action, i) => (\n        <button\n          key={i}\n          type=\"button\"\n          onClick={action.onClick}\n          data-slot=\"styled-button-group-item\"\n          className={cn(item, itemClassName, sizes[size])}\n        >\n          {action.icon}\n          {action.label}\n        </button>\n      ))}\n    </div>\n  )\n}\n\n/* Frost: a neutral frosted-glass container. Depth = md (8px), the canonical default - the container's \"normal\" state, the same language as glass.overlay. The surface and the signature come entirely from the library. */\nexport function FrostButtonGroup(props: GroupProps) {\n  return (\n    <GlassShell\n      props={props}\n      label=\"Frost actions\"\n      shellClassName={cn(\n        glassDepth.md,\n        \"border-[color-mix(in_oklab,var(--color-foreground)_10%,transparent)]\"\n      )}\n      itemClassName=\"text-foreground hover:bg-[color-mix(in_oklab,var(--color-foreground)_8%,transparent)]\"\n    />\n  )\n}\n\n/* Tint: an info-toned frosted-glass container. Depth = md (8px) - the same step as Frost, DELIBERATELY: the axis separating these two is hue, not depth. The tone is info: primary/brand sits on the neutral ramp (chroma ~0.005), so it would be an invisible tint. bg overrides the library's (the tint is the surface itself); the supports- variant is overridden too, otherwise the library's supports-[backdrop-filter]:bg-background/60 would take the tint back. */\nexport function TintButtonGroup(props: GroupProps) {\n  return (\n    <GlassShell\n      props={props}\n      label=\"Tint actions\"\n      shellClassName={cn(\n        glassDepth.md,\n        \"border-[color-mix(in_oklab,var(--color-info)_24%,transparent)]\",\n        \"bg-[color-mix(in_oklab,var(--color-info)_12%,transparent)] supports-[backdrop-filter]:bg-[color-mix(in_oklab,var(--color-info)_12%,transparent)]\"\n      )}\n      itemClassName=\"text-foreground hover:bg-[color-mix(in_oklab,var(--color-info)_18%,transparent)]\"\n    />\n  )\n}\n\n/* Smoke: a dark, smoky scrim. Depth = lg (16px) - one of the two deepest steps in the file. A scrim's job is to stop what is underneath being text and turn it into texture; because the container is wide enough, that job is genuinely visible here (putting the same value on an h-5 badge would be a waste). Neutral: what separates it from Tint is the absence of hue. */\nexport function SmokeButtonGroup(props: GroupProps) {\n  return (\n    <GlassShell\n      props={props}\n      label=\"Smoke actions\"\n      shellClassName={cn(\n        glassDepth.lg,\n        \"border-[color-mix(in_oklab,var(--color-foreground)_16%,transparent)]\",\n        \"bg-[color-mix(in_oklab,var(--color-foreground)_14%,transparent)] supports-[backdrop-filter]:bg-[color-mix(in_oklab,var(--color-foreground)_14%,transparent)]\"\n      )}\n      itemClassName=\"text-foreground hover:bg-[color-mix(in_oklab,var(--color-foreground)_12%,transparent)]\"\n    />\n  )\n}\n\n/* Crystal: an almost transparent container. Depth = sm (4px), the least diffusing in the family. It used to be blur-xl (24px), which contradicted its own name: you should be able to see through an \"almost transparent\" container. The inner highlight edge is no longer hand-made but the library signature itself - writing a second inset on top would erase the signature through twMerge. */\nexport function CrystalButtonGroup(props: GroupProps) {\n  return (\n    <GlassShell\n      props={props}\n      label=\"Crystal actions\"\n      shellClassName={cn(\n        glassDepth.sm,\n        \"border-[color-mix(in_oklab,var(--color-background)_70%,transparent)]\"\n      )}\n      itemClassName=\"text-foreground hover:bg-[color-mix(in_oklab,var(--color-background)_55%,transparent)]\"\n    />\n  )\n}\n\n/* Depth: a frosted container plus a lifting shadow. Depth = lg (16px): this is the variation that leaves the plane, and under a lifted bar a real gap forms for the blur to scatter. The shadow uses drop-shadow (the filter group): writing shadow-lg on the container would silently erase the library signature in box-shadow. The same step as Smoke, DELIBERATELY - the axis separating those two is the lift (shadow), not the smoke (tint). */\nexport function DepthButtonGroup(props: GroupProps) {\n  return (\n    <GlassShell\n      props={props}\n      label=\"Depth actions\"\n      shellClassName={cn(\n        glassDepth.lg,\n        \"border-[color-mix(in_oklab,var(--color-foreground)_12%,transparent)] drop-shadow-lg\"\n      )}\n      itemClassName=\"text-foreground shadow-[inset_0_0_0_1px_color-mix(in_oklab,var(--color-foreground)_6%,transparent)] hover:bg-[color-mix(in_oklab,var(--color-background)_75%,transparent)]\"\n    />\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/button-group-glass.tsx"
    }
  ],
  "categories": [
    "styled",
    "button"
  ],
  "type": "registry:component"
}