{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "ui95",
  "homepage": "https://www.ui95.dev",
  "items": [
    {
      "name": "theme",
      "type": "registry:style",
      "title": "Dither theme",
      "description": "Retro tokens, phosphor and cyan-pixel palettes, dither, bevel and offset-shadow utilities.",
      "docs": "The default look pairs Silkscreen for titles and labels with VT323 for body text, both free on Google Fonts. Load those, or any pixel display font and monospace body font you prefer, and expose them as --font-display and --font-body (with next/font/google, pass them as the variable option). The data-theme attribute on <html> picks the palette, and the dark class switches it to dark mode.",
      "cssVars": {
        "theme": {
          "font-heading": "var(--font-pixel)",
          "font-sans": "var(--font-mono)",
          "font-mono": "var(--font-mono)",
          "font-pixel": "var(--font-pixel)",
          "color-ink-0": "var(--ink-0)",
          "color-ink-1": "var(--ink-1)",
          "color-ink-2": "var(--ink-2)",
          "color-ink-3": "var(--ink-3)",
          "color-desktop": "var(--desktop)",
          "color-bevel-hi": "var(--bevel-hi)",
          "color-bevel-lo": "var(--bevel-lo)",
          "color-well": "var(--well)",
          "color-well-foreground": "var(--well-foreground)",
          "color-well-muted": "var(--well-muted)",
          "color-well-fill": "var(--well-fill)",
          "color-titlebar": "var(--titlebar)",
          "color-titlebar-foreground": "var(--titlebar-foreground)",
          "color-sidebar-ring": "var(--sidebar-ring)",
          "color-sidebar-border": "var(--sidebar-border)",
          "color-sidebar-accent-foreground": "var(--sidebar-accent-foreground)",
          "color-sidebar-accent": "var(--sidebar-accent)",
          "color-sidebar-primary-foreground": "var(--sidebar-primary-foreground)",
          "color-sidebar-primary": "var(--sidebar-primary)",
          "color-sidebar-foreground": "var(--sidebar-foreground)",
          "color-sidebar": "var(--sidebar)",
          "color-chart-5": "var(--chart-5)",
          "color-chart-4": "var(--chart-4)",
          "color-chart-3": "var(--chart-3)",
          "color-chart-2": "var(--chart-2)",
          "color-chart-1": "var(--chart-1)",
          "color-ring": "var(--ring)",
          "color-input": "var(--input)",
          "color-border": "var(--border)",
          "color-destructive": "var(--destructive)",
          "color-accent-foreground": "var(--accent-foreground)",
          "color-accent": "var(--accent)",
          "color-muted-foreground": "var(--muted-foreground)",
          "color-muted": "var(--muted)",
          "color-secondary-foreground": "var(--secondary-foreground)",
          "color-secondary": "var(--secondary)",
          "color-primary-foreground": "var(--primary-foreground)",
          "color-primary": "var(--primary)",
          "color-popover-foreground": "var(--popover-foreground)",
          "color-popover": "var(--popover)",
          "color-card-foreground": "var(--card-foreground)",
          "color-card": "var(--card)",
          "color-foreground": "var(--foreground)",
          "color-background": "var(--background)",
          "radius-sm": "calc(var(--radius) * 0.6)",
          "radius-md": "calc(var(--radius) * 0.8)",
          "radius-lg": "var(--radius)",
          "radius-xl": "calc(var(--radius) * 1.4)",
          "radius-2xl": "calc(var(--radius) * 1.8)",
          "radius-3xl": "calc(var(--radius) * 2.2)",
          "radius-4xl": "calc(var(--radius) * 2.6)"
        },
        "light": {
          "ink-0": "#20231a",
          "ink-1": "#4b5036",
          "ink-2": "#888c62",
          "ink-3": "#c4c79d",
          "ink-4": "#eeefc8",
          "desktop": "#a7ab7f",
          "wallpaper-0": "var(--ink-0)",
          "wallpaper-1": "var(--ink-1)",
          "wallpaper-2": "var(--desktop)",
          "wallpaper-3": "var(--ink-4)",
          "titlebar": "var(--ink-0)",
          "titlebar-foreground": "var(--ink-3)",
          "bevel-hi": "var(--ink-3)",
          "bevel-lo": "var(--ink-1)",
          "bevel-glint": "var(--ink-4)",
          "bevel-shade": "var(--ink-2)",
          "well": "var(--ink-1)",
          "well-foreground": "var(--ink-3)",
          "well-muted": "var(--ink-2)",
          "well-rim": "var(--ink-0)",
          "well-fill": "var(--ink-4)",
          "keycap": "var(--ink-1)",
          "keycap-foreground": "var(--ink-3)",
          "keycap-wall-hi": "var(--ink-2)",
          "keycap-wall-lo": "var(--ink-0)",
          "keycap-outline": "var(--ink-0)",
          "pixel": "2px",
          "font-pixel": "var(--font-display), \"Silkscreen\", ui-monospace, monospace",
          "font-mono": "var(--font-body), \"VT323\", ui-monospace, monospace",
          "background": "var(--desktop)",
          "foreground": "var(--ink-0)",
          "card": "var(--ink-3)",
          "card-foreground": "var(--ink-0)",
          "popover": "var(--ink-3)",
          "popover-foreground": "var(--ink-0)",
          "primary": "var(--ink-0)",
          "primary-foreground": "var(--ink-3)",
          "secondary": "var(--ink-2)",
          "secondary-foreground": "var(--ink-0)",
          "muted": "var(--ink-2)",
          "muted-foreground": "var(--ink-1)",
          "accent": "var(--ink-1)",
          "accent-foreground": "var(--ink-3)",
          "destructive": "var(--ink-0)",
          "border": "var(--ink-0)",
          "input": "var(--ink-4)",
          "ring": "var(--ink-0)",
          "chart-1": "var(--ink-0)",
          "chart-2": "var(--ink-1)",
          "chart-3": "var(--ink-2)",
          "chart-4": "var(--ink-3)",
          "chart-5": "var(--desktop)",
          "radius": "0rem",
          "sidebar": "var(--ink-3)",
          "sidebar-foreground": "var(--ink-0)",
          "sidebar-primary": "var(--ink-0)",
          "sidebar-primary-foreground": "var(--ink-3)",
          "sidebar-accent": "var(--ink-2)",
          "sidebar-accent-foreground": "var(--ink-0)",
          "sidebar-border": "var(--ink-0)",
          "sidebar-ring": "var(--ink-0)"
        },
        "dark": {
          "ink-0": "#10120b",
          "ink-1": "#2c301f",
          "ink-2": "#6a714a",
          "ink-3": "#b5bc87",
          "ink-4": "#474830",
          "desktop": "#1a1d12",
          "wallpaper-0": "var(--ink-3)",
          "wallpaper-1": "var(--ink-2)",
          "wallpaper-2": "var(--ink-1)",
          "wallpaper-3": "var(--desktop)",
          "titlebar": "var(--ink-2)",
          "titlebar-foreground": "var(--ink-0)",
          "keycap": "var(--ink-2)",
          "keycap-foreground": "var(--ink-0)",
          "keycap-wall-hi": "var(--ink-3)",
          "keycap-wall-lo": "var(--ink-1)",
          "keycap-outline": "var(--ink-0)",
          "bevel-hi": "var(--ink-2)",
          "bevel-lo": "var(--ink-0)",
          "bevel-glint": "var(--ink-3)",
          "bevel-shade": "var(--ink-3)",
          "well": "var(--ink-0)",
          "well-foreground": "var(--ink-3)",
          "well-muted": "var(--ink-2)",
          "well-rim": "var(--ink-2)",
          "well-fill": "var(--ink-3)",
          "background": "var(--desktop)",
          "foreground": "var(--ink-3)",
          "card": "var(--ink-0)",
          "card-foreground": "var(--ink-3)",
          "popover": "var(--ink-0)",
          "popover-foreground": "var(--ink-3)",
          "primary": "var(--ink-3)",
          "primary-foreground": "var(--ink-0)",
          "secondary": "var(--ink-1)",
          "secondary-foreground": "var(--ink-3)",
          "muted": "var(--ink-1)",
          "muted-foreground": "var(--ink-2)",
          "accent": "var(--ink-2)",
          "accent-foreground": "var(--ink-0)",
          "destructive": "var(--ink-3)",
          "border": "var(--ink-3)",
          "input": "var(--ink-4)",
          "ring": "var(--ink-3)",
          "chart-1": "var(--ink-3)",
          "chart-2": "var(--ink-2)",
          "chart-3": "var(--ink-1)",
          "chart-4": "var(--ink-0)",
          "chart-5": "var(--desktop)",
          "sidebar": "var(--ink-0)",
          "sidebar-foreground": "var(--ink-3)",
          "sidebar-primary": "var(--ink-3)",
          "sidebar-primary-foreground": "var(--ink-0)",
          "sidebar-accent": "var(--ink-1)",
          "sidebar-accent-foreground": "var(--ink-3)",
          "sidebar-border": "var(--ink-3)",
          "sidebar-ring": "var(--ink-3)"
        }
      },
      "css": {
        "[data-theme=\"cyan-pixel\"]": {
          "--ink-0": "#111111",
          "--ink-1": "#4a4a43",
          "--ink-2": "#a9a491",
          "--ink-3": "#efe8d5",
          "--ink-4": "rgb(187, 181, 164)",
          "--desktop": "#8ed5f6",
          "--wallpaper-0": "#75bee0",
          "--wallpaper-1": "#69a5c1",
          "--wallpaper-2": "var(--desktop)",
          "--wallpaper-3": "var(--wallpaper-0)",
          "--titlebar": "var(--ink-3)",
          "--titlebar-foreground": "var(--ink-0)"
        },
        "[data-theme=\"cyan-pixel\"]:not(.dark)": {
          "--bevel-shade": "var(--ink-4)"
        },
        ".dark[data-theme=\"cyan-pixel\"]": {
          "--ink-0": "#0a0d10",
          "--ink-1": "#243139",
          "--ink-2": "#7b8e95",
          "--ink-3": "#e5eee7",
          "--ink-4": "#455b64",
          "--desktop": "#0b4d70",
          "--wallpaper-0": "#1b495f",
          "--wallpaper-1": "#103246",
          "--wallpaper-2": "#0b4d70",
          "--wallpaper-3": "#083c57",
          "--titlebar": "var(--ink-3)",
          "--titlebar-foreground": "var(--ink-0)"
        },
        "[data-theme=\"retro-candy\"]": {
          "--ink-0": "#231A21",
          "--ink-1": "#50364A",
          "--ink-2": "#e597b4",
          "--ink-3": "#f1cfdf",
          "--ink-4": "#fdf3f8",
          "--desktop": "#daf7c7",
          "--titlebar": "var(--ink-2)",
          "--titlebar-foreground": "var(--ink-0)",
          "--muted": "#caaebb"
        },
        ".dark[data-theme=\"retro-candy\"]": {
          "--ink-0": "#1c1217",
          "--ink-1": "#3d2631",
          "--ink-2": "#b8668a",
          "--ink-3": "#f1cfdf",
          "--ink-4": "#643f53",
          "--desktop": "#253024",
          "--titlebar": "var(--ink-2)",
          "--titlebar-foreground": "var(--ink-0)",
          "--muted": "var(--ink-1)",
          "--muted-foreground": "#6d4c5b"
        },
        "[data-theme=\"soul-green\"]": {
          "--ink-0": "#10392d",
          "--ink-1": "#2d5343",
          "--ink-2": "#c8e597",
          "--ink-3": "#e0e4c5",
          "--ink-4": "#f0f3d9",
          "--desktop": "#f0f7c7",
          "--titlebar": "var(--ink-2)",
          "--titlebar-foreground": "var(--ink-0)",
          "--muted": "#bbcaae",
          "--bevel-lo": "var(--ink-1)",
          "--well-muted": "var(--muted)"
        },
        ".dark[data-theme=\"soul-green\"]": {
          "--ink-0": "#1d3f32",
          "--ink-1": "#1b2b16",
          "--ink-2": "#d0f1be",
          "--ink-3": "#bac994",
          "--ink-4": "#0c0c4b",
          "--desktop": "#1d231d",
          "--titlebar": "var(--ink-2)",
          "--titlebar-foreground": "var(--ink-0)",
          "--muted": "#2b3423",
          "--muted-foreground": "#56684a",
          "--bevel-lo": "var(--ink-4)",
          "--bevel-hi": "var(--ink-4)",
          "--well-muted": "var(--ink-1)"
        },
        "[data-theme=\"95\"]": {
          "--ink-0": "#000000",
          "--ink-1": "#808080",
          "--ink-2": "#a0a0a0",
          "--ink-3": "#c0c0c0",
          "--ink-4": "#ffffff",
          "--desktop": "#aaaaaa",
          "--titlebar": "#000080",
          "--titlebar-foreground": "var(--ink-4)",
          "--wallpaper-0": "#008080",
          "--wallpaper-1": "rgb(1, 117, 117)",
          "--wallpaper-2": "#008080",
          "--wallpaper-3": "rgb(1, 136, 136)",
          "--keycap": "var(--ink-3)",
          "--keycap-foreground": "var(--ink-0)",
          "--keycap-wall-hi": "var(--ink-4)",
          "--keycap-wall-lo": "var(--ink-1)",
          "--keycap-outline": "var(--ink-0)"
        },
        ".dark[data-theme=\"95\"]": {
          "--ink-0": "#000000",
          "--ink-1": "#404040",
          "--ink-2": "#808080",
          "--ink-3": "#c0c0c0",
          "--ink-4": "#606060",
          "--desktop": "#333333",
          "--titlebar": "#000080",
          "--titlebar-foreground": "var(--ink-3)",
          "--wallpaper-0": "#004040",
          "--wallpaper-1": "#045353",
          "--wallpaper-2": "#024a4a",
          "--wallpaper-3": "var(--wallpaper-0)",
          "--keycap": "var(--ink-2)",
          "--keycap-foreground": "var(--ink-0)",
          "--keycap-wall-hi": "var(--ink-3)",
          "--keycap-wall-lo": "var(--ink-1)"
        },
        "@utility dither-25": {
          "mask-image": "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4' shape-rendering='crispEdges'%3E%3Crect x='0' y='0' width='1' height='1'/%3E%3Crect x='2' y='0' width='1' height='1'/%3E%3Crect x='0' y='2' width='1' height='1'/%3E%3Crect x='2' y='2' width='1' height='1'/%3E%3C/svg%3E\")",
          "mask-size": "calc(var(--pixel) * 4) calc(var(--pixel) * 4)",
          "mask-repeat": "repeat"
        },
        "@utility dither-50": {
          "mask-image": "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4' shape-rendering='crispEdges'%3E%3Crect x='0' y='0' width='1' height='1'/%3E%3Crect x='2' y='0' width='1' height='1'/%3E%3Crect x='1' y='1' width='1' height='1'/%3E%3Crect x='3' y='1' width='1' height='1'/%3E%3Crect x='0' y='2' width='1' height='1'/%3E%3Crect x='2' y='2' width='1' height='1'/%3E%3Crect x='1' y='3' width='1' height='1'/%3E%3Crect x='3' y='3' width='1' height='1'/%3E%3C/svg%3E\")",
          "mask-size": "calc(var(--pixel) * 4) calc(var(--pixel) * 4)",
          "mask-repeat": "repeat"
        },
        "@utility dither-75": {
          "mask-image": "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4' shape-rendering='crispEdges'%3E%3Crect x='0' y='0' width='1' height='1'/%3E%3Crect x='1' y='0' width='1' height='1'/%3E%3Crect x='2' y='0' width='1' height='1'/%3E%3Crect x='3' y='0' width='1' height='1'/%3E%3Crect x='1' y='1' width='1' height='1'/%3E%3Crect x='3' y='1' width='1' height='1'/%3E%3Crect x='0' y='2' width='1' height='1'/%3E%3Crect x='1' y='2' width='1' height='1'/%3E%3Crect x='2' y='2' width='1' height='1'/%3E%3Crect x='3' y='2' width='1' height='1'/%3E%3Crect x='1' y='3' width='1' height='1'/%3E%3Crect x='3' y='3' width='1' height='1'/%3E%3C/svg%3E\")",
          "mask-size": "calc(var(--pixel) * 4) calc(var(--pixel) * 4)",
          "mask-repeat": "repeat"
        },
        "@utility stripes": {
          "background-color": "currentColor",
          "mask-image": "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 2' preserveAspectRatio='none' shape-rendering='crispEdges'%3E%3Crect width='1' height='1'/%3E%3C/svg%3E\")",
          "mask-size": "100% calc(var(--pixel) * 2)",
          "mask-repeat": "repeat-y"
        },
        "@utility segments": {
          "mask-image": "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 1' preserveAspectRatio='none' shape-rendering='crispEdges'%3E%3Crect width='2' height='1'/%3E%3C/svg%3E\")",
          "mask-size": "calc(var(--pixel) * 3) 100%",
          "mask-repeat": "repeat-x"
        },
        "@utility pixel-border": {
          "border-style": "solid",
          "border-width": "var(--pixel)"
        },
        "@utility bevel-raised": {
          "--bevel-shadow": "inset calc(var(--pixel) * -1) calc(var(--pixel) * -1) 0 0 var(--bevel-lo), inset var(--pixel) var(--pixel) 0 0 var(--bevel-glint)",
          "box-shadow": "var(--offset-shadow, 0 0 0 0 transparent), var(--bevel-shadow)"
        },
        "@utility bevel-sunken": {
          "--bevel-shadow": "inset var(--pixel) var(--pixel) 0 0 var(--bevel-lo), inset calc(var(--pixel) * -1) calc(var(--pixel) * -1) 0 0 var(--bevel-glint)",
          "box-shadow": "var(--offset-shadow, 0 0 0 0 transparent), var(--bevel-shadow)"
        },
        "@utility well": {
          "background-color": "var(--well)",
          "color": "var(--well-foreground)",
          "box-shadow": "inset var(--pixel) var(--pixel) 0 0 var(--well-rim), var(--pixel) var(--pixel) 0 0 var(--bevel-shade)"
        },
        "@utility dither-shadow": {
          "&::before": {
            "content": "\"\"",
            "position": "absolute",
            "inset": "calc(var(--pixel) * -1)",
            "translate": "calc(var(--pixel) * 3) calc(var(--pixel) * 3)",
            "background-color": "var(--foreground)",
            "mask-image": "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4' shape-rendering='crispEdges'%3E%3Crect x='0' y='0' width='1' height='1'/%3E%3Crect x='2' y='0' width='1' height='1'/%3E%3Crect x='1' y='1' width='1' height='1'/%3E%3Crect x='3' y='1' width='1' height='1'/%3E%3Crect x='0' y='2' width='1' height='1'/%3E%3Crect x='2' y='2' width='1' height='1'/%3E%3Crect x='1' y='3' width='1' height='1'/%3E%3Crect x='3' y='3' width='1' height='1'/%3E%3C/svg%3E\")",
            "mask-size": "calc(var(--pixel) * 4) calc(var(--pixel) * 4)",
            "clip-path": "polygon(calc(100% - var(--pixel) * 3) 0, 100% 0, 100% 100%, 0 100%, 0 calc(100% - var(--pixel) * 3), calc(100% - var(--pixel) * 3) calc(100% - var(--pixel) * 3))",
            "pointer-events": "none"
          }
        },
        "@utility bevel-frame": {
          "&::after": {
            "content": "\"\"",
            "position": "absolute",
            "inset": "0",
            "z-index": "1",
            "box-shadow": "inset var(--pixel) var(--pixel) 0 0 var(--bevel-glint), inset calc(var(--pixel) * -1) calc(var(--pixel) * -1) 0 0 var(--bevel-lo)",
            "pointer-events": "none"
          }
        },
        "@utility offset-shadow-*": {
          "--offset-shadow": "calc(var(--pixel) * --value(integer)) calc(var(--pixel) * --value(integer)) 0 0 var(--foreground)",
          "box-shadow": "var(--offset-shadow), var(--bevel-shadow, 0 0 0 0 transparent)"
        },
        "@utility offset-shadow-none": {
          "--offset-shadow": "0 0 0 0 transparent",
          "box-shadow": "var(--offset-shadow), var(--bevel-shadow, 0 0 0 0 transparent)"
        },
        "@utility pixelated": {
          "image-rendering": "pixelated"
        },
        "@utility animate-blink": {
          "animation": "blink 1s steps(1, end) infinite"
        },
        "@keyframes blink": {
          "50%": {
            "opacity": "0"
          }
        },
        "@layer base": {
          "*": {
            "@apply border-border outline-ring": {}
          },
          "html": {
            "@apply font-mono": {},
            "-webkit-font-smoothing": "none",
            "-moz-osx-font-smoothing": "unset",
            "font-smooth": "never"
          },
          "body": {
            "@apply bg-background text-foreground text-lg leading-tight": {}
          },
          "::selection": {
            "background-color": "var(--foreground)",
            "color": "var(--background)"
          },
          "canvas,\n  img": {
            "image-rendering": "pixelated"
          },
          ":where(button, select, summary, label[for], [role=\"button\"], [role=\"tab\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"], [role=\"slider\"], [role=\"option\"], [role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"], input:is([type=\"checkbox\"], [type=\"radio\"], [type=\"range\"], [type=\"file\"], [type=\"color\"], [type=\"submit\"], [type=\"button\"], [type=\"reset\"]))": {
            "cursor": "pointer"
          },
          ":where(button, select, input, [role]):where(:disabled, [aria-disabled=\"true\"], [data-disabled])": {
            "cursor": "default"
          },
          "[data-vaul-drawer],\n  [data-vaul-overlay],\n  [data-sonner-toast]": {
            "transition": "none",
            "animation": "none"
          },
          ":focus-visible": {
            "outline-style": "dashed",
            "outline-width": "var(--pixel)",
            "outline-offset": "var(--pixel)"
          }
        }
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "pixel-glyphs",
      "type": "registry:lib",
      "title": "Pixel glyphs",
      "description": "Crisp pixel glyphs shared by the primitives: check, minus, close, chevron, arrow, dot, radio, error and 16x16 folder, document and terminal icons.",
      "dependencies": [
        "cn"
      ],
      "files": [
        {
          "path": "components/ui/pixel-glyphs.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "dither-inks",
      "type": "registry:lib",
      "title": "Dither inks",
      "description": "Reads theme colors through a canvas probe and observes <html> for theme changes.",
      "files": [
        {
          "path": "lib/dither/inks.ts",
          "type": "registry:lib",
          "target": "@lib/dither/inks.ts"
        }
      ],
      "categories": [
        "shared"
      ]
    },
    {
      "name": "dither-image",
      "type": "registry:ui",
      "title": "Dither image",
      "description": "Ordered Bayer dithering quantized to the theme inks, or to two to four colors of your own.",
      "dependencies": [
        "cn"
      ],
      "files": [
        {
          "path": "components/ui/dither-image.tsx",
          "type": "registry:ui"
        },
        {
          "path": "lib/dither/bayer.ts",
          "type": "registry:lib",
          "target": "@lib/dither/bayer.ts"
        },
        {
          "path": "lib/dither/ditherOnCpu.ts",
          "type": "registry:lib",
          "target": "@lib/dither/ditherOnCpu.ts"
        },
        {
          "path": "lib/dither/useInkVersion.ts",
          "type": "registry:lib",
          "target": "@lib/dither/useInkVersion.ts"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/dither-inks"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "shader-mount",
      "type": "registry:lib",
      "title": "Shader mount",
      "description": "WebGL2 mount for fragment shaders with stepped time, theme color uniforms and the --pixel grid, plus its React wrapper.",
      "files": [
        {
          "path": "lib/shaders/types.ts",
          "type": "registry:lib",
          "target": "@lib/shaders/types.ts"
        },
        {
          "path": "lib/shaders/shader-mount-core.ts",
          "type": "registry:lib",
          "target": "@lib/shaders/shader-mount-core.ts"
        },
        {
          "path": "components/ui/shader-mount.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/dither-inks"
      ],
      "categories": [
        "shared"
      ]
    },
    {
      "name": "use-prefers-reduced-motion",
      "type": "registry:lib",
      "title": "usePrefersReducedMotion",
      "description": "Hook that reports the prefers-reduced-motion media query and stays true on the server so motion starts off.",
      "files": [
        {
          "path": "hooks/use-prefers-reduced-motion.ts",
          "type": "registry:hook"
        }
      ],
      "categories": [
        "shared"
      ]
    },
    {
      "name": "dither-shine",
      "type": "registry:ui",
      "title": "Dither shine",
      "description": "A two-color Bayer-dithered band that sweeps corner to corner at a stepped frame rate.",
      "files": [
        {
          "path": "lib/shaders/dither-shine.ts",
          "type": "registry:lib",
          "target": "@lib/shaders/dither-shine.ts"
        },
        {
          "path": "components/ui/dither-shine.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/shader-mount"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "sound",
      "type": "registry:lib",
      "title": "Sound",
      "description": "Tactile synthesized sounds for UI95 components: one shared AudioContext, sounds configured in sounds.json, played by event delegation on each component's data-slot.",
      "docs": "Render <Ui95Sounds /> once in your root layout. Sounds live in sounds.json next to components.json (in src/ if @/* maps to ./src/*). After adding UI95 components run: node scripts/95-sound-lib.mjs sync. It adds only the sounds of installed components and keeps your edits. Silence one element with data-sound=\"none\", rename its sound with data-sound=\"my-key\", silence a sound with \"key\": false, or everything with \"enabled\": false.",
      "files": [
        {
          "path": "lib/sound/types.ts",
          "type": "registry:lib",
          "target": "@lib/sound/types.ts"
        },
        {
          "path": "lib/sound/render.ts",
          "type": "registry:lib",
          "target": "@lib/sound/render.ts"
        },
        {
          "path": "lib/sound/sound-engine.ts",
          "type": "registry:lib",
          "target": "@lib/sound/sound-engine.ts"
        },
        {
          "path": "lib/sound/sound-slots.ts",
          "type": "registry:lib",
          "target": "@lib/sound/sound-slots.ts"
        },
        {
          "path": "lib/sound/config.ts",
          "type": "registry:lib",
          "target": "@lib/sound/config.ts"
        },
        {
          "path": "hooks/use-sound.ts",
          "type": "registry:hook"
        },
        {
          "path": "components/ui/ui95-sounds.tsx",
          "type": "registry:ui"
        },
        {
          "path": "lib/sound/sounds.template.json",
          "type": "registry:file",
          "target": "~/sounds.json"
        },
        {
          "path": "scripts/95-sound-lib.mjs",
          "type": "registry:file",
          "target": "~/scripts/95-sound-lib.mjs"
        }
      ],
      "categories": [
        "shared"
      ]
    },
    {
      "name": "hardware",
      "type": "registry:ui",
      "title": "Hardware95 foundation",
      "description": "The base of every Hardware95 part: shared material, legend, accent, bevel and shadow tokens, a matte plastic Faceplate in putty, cream or khaki, printed Legend text and a glass pilot Lamp.",
      "docs": "Hardware95 parts style themselves under [data-hw] and never touch your shadcn theme, so they drop into any app. Faceplate takes finish=\"putty\" | \"cream\" | \"khaki\" and draws corner screws unless screws={false}. Legend prints condensed caps onto the panel in size sm, md or lg. Lamp takes on and tone=\"red\" | \"amber\" | \"green\". Every color and depth recipe is a --hw-* custom property, so override one on any ancestor to restyle every part inside it.",
      "categories": [
        "hardware"
      ],
      "files": [
        {
          "path": "components/hardware/hardware.css",
          "type": "registry:component",
          "target": "@components/hardware/hardware.css"
        },
        {
          "path": "components/hardware/faceplate.tsx",
          "type": "registry:component",
          "target": "@components/hardware/faceplate.tsx"
        },
        {
          "path": "components/hardware/lamp.tsx",
          "type": "registry:component",
          "target": "@components/hardware/lamp.tsx"
        }
      ]
    },
    {
      "name": "rotary-knob",
      "type": "registry:ui",
      "title": "Rotary knob",
      "description": "A matte charcoal plastic knob with a white indicator line over a scale printed on the faceplate, as a skirted knob or a pointer knob. Turn it by dragging, scrolling or with the arrow keys, and it clicks at each tick.",
      "docs": "variant=\"skirted\" | \"pointer\" picks the knob shape, and cap=\"red\" | \"amber\" | \"green\" | \"slate\" adds a coloured cap insert. Drag up or right to turn it up, and hold Shift for fine control. The wheel and the arrow keys move one step, Page Up and Page Down a tenth of the range, Home and End to the stops. It is a role=\"slider\", so screen readers announce its value. The light stays at the top-left while the knob turns. With the sound item installed, data-slot=\"rotary-knob\" plays knob.tick at each printed tick.",
      "categories": [
        "hardware"
      ],
      "registryDependencies": [
        "@ui95/hardware"
      ],
      "files": [
        {
          "path": "components/hardware/rotary-knob.css",
          "type": "registry:component",
          "target": "@components/hardware/rotary-knob.css"
        },
        {
          "path": "components/hardware/rotary-knob.tsx",
          "type": "registry:component",
          "target": "@components/hardware/rotary-knob.tsx"
        }
      ],
      "meta": {
        "sounds": [
          "knob.tick"
        ]
      }
    },
    {
      "name": "crt-monitor",
      "type": "registry:ui",
      "title": "CRT monitor",
      "description": "A beige monitor housing with a charcoal bezel, a curved CRT screen, a glass reflection, vents, a model badge and a power key. Whatever you put inside runs on the screen.",
      "docs": "Render any content as children; it runs inside the CRT effect from crt-screen. on and onPowerChange control it, or pass defaultOn={false} to start dark. brightness (0.4 to 1.4) and curvature set the picture. Put knobs or lamps in the controls slot and they sit in the chin next to the power key. Turning it on plays a short warm-up that reduced motion skips.",
      "categories": [
        "hardware"
      ],
      "registryDependencies": [
        "@ui95/hardware",
        "@ui95/crt-screen"
      ],
      "files": [
        {
          "path": "components/hardware/crt-monitor.css",
          "type": "registry:component",
          "target": "@components/hardware/crt-monitor.css"
        },
        {
          "path": "components/hardware/crt-monitor.tsx",
          "type": "registry:component",
          "target": "@components/hardware/crt-monitor.tsx"
        }
      ]
    },
    {
      "name": "button",
      "type": "registry:ui",
      "title": "Button",
      "description": "shadcn button reskinned with pixel borders and offset shadows.",
      "dependencies": [
        "cn",
        "class-variance-authority",
        "radix-ui"
      ],
      "files": [
        {
          "path": "components/ui/button.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release",
          "small-button.press",
          "small-button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "cta-button",
      "type": "registry:ui",
      "title": "CTA Button",
      "description": "Call-to-action button over a WebGL dither shine that sweeps at 10 fps, with a stepped pixel tilt toward the pointer on hover.",
      "dependencies": [
        "cn",
        "class-variance-authority",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/dither-shine",
        "@ui95/use-prefers-reduced-motion"
      ],
      "files": [
        {
          "path": "components/ui/cta-button.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "keycap.press",
          "keycap.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "checkbox",
      "type": "registry:ui",
      "title": "Checkbox",
      "description": "shadcn checkbox with a pixel check.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "files": [
        {
          "path": "components/ui/checkbox.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "checkbox.on",
          "checkbox.off"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "slider",
      "type": "registry:ui",
      "title": "Slider",
      "description": "shadcn slider with a dithered range.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "files": [
        {
          "path": "components/ui/slider.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "meta": {
        "sounds": [
          "slider.tick"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "progress",
      "type": "registry:ui",
      "title": "Progress",
      "description": "shadcn progress drawn as segmented blocks.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "files": [
        {
          "path": "components/ui/progress.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "dialog",
      "type": "registry:ui",
      "title": "Dialog",
      "description": "shadcn dialog with a striped title bar and a dithered overlay.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/pixel-glyphs"
      ],
      "files": [
        {
          "path": "components/ui/dialog.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "input",
      "type": "registry:ui",
      "title": "Input",
      "description": "shadcn input as a sunken 1-bit field.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/input.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "typewriter.key",
          "typewriter.space",
          "typewriter.return"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "textarea",
      "type": "registry:ui",
      "title": "Textarea",
      "description": "shadcn textarea as a sunken 1-bit field that grows with its content.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/textarea.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "typewriter.key",
          "typewriter.space",
          "typewriter.return"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "label",
      "type": "registry:ui",
      "title": "Label",
      "description": "shadcn label set in the pixel font.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/label.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "radio-group",
      "type": "registry:ui",
      "title": "Radio group",
      "description": "shadcn radio group with a pixel ring and dot.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "files": [
        {
          "path": "components/ui/radio-group.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "radio.select"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "switch",
      "type": "registry:ui",
      "title": "Switch",
      "description": "shadcn switch as a two-state pixel toggle with a dithered on side.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/switch.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "switch.on",
          "switch.off"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "select",
      "type": "registry:ui",
      "title": "Select",
      "description": "shadcn select as a Win95 combo box that drops a menu with no animation.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "files": [
        {
          "path": "components/ui/select.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release",
          "menu.select"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "tabs",
      "type": "registry:ui",
      "title": "Tabs",
      "description": "shadcn tabs as raised bevelled folder tabs joined to a bevelled panel, or an underline.",
      "dependencies": [
        "cn",
        "class-variance-authority",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/tabs.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "tab.select"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "tooltip",
      "type": "registry:ui",
      "title": "Tooltip",
      "description": "shadcn tooltip as a cream box with a hard offset shadow.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/tooltip.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "dropdown-menu",
      "type": "registry:ui",
      "title": "Dropdown menu",
      "description": "shadcn dropdown menu with Win95 inverted highlight, etched separators and pixel indicators.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "files": [
        {
          "path": "components/ui/dropdown-menu.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "menu.select"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "menubar",
      "type": "registry:ui",
      "title": "Menubar",
      "description": "shadcn menubar with Win95 menus.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "files": [
        {
          "path": "components/ui/menubar.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "sounds": [
          "menu.select"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "scroll-area",
      "type": "registry:ui",
      "title": "Scroll area",
      "description": "shadcn scroll area with a dithered track and a beveled thumb.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/scroll-area.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "separator",
      "type": "registry:ui",
      "title": "Separator",
      "description": "shadcn separator as an etched line.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/separator.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "badge",
      "type": "registry:ui",
      "title": "Badge",
      "description": "shadcn badge as a pixel tag.",
      "dependencies": [
        "cn",
        "class-variance-authority",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/badge.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "plate",
      "type": "registry:ui",
      "title": "Plate",
      "description": "A surface for text that would otherwise sit on the desktop: a raised panel, a sunken readout or a title-bar caption tag.",
      "dependencies": [
        "cn",
        "class-variance-authority",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/plate.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "highlighted-text",
      "type": "registry:ui",
      "title": "Highlighted text",
      "description": "Text with dithered pixel stars that twinkle on its corners in stepped frames, each corner on its own beat.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/highlighted-text.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "alert",
      "type": "registry:ui",
      "title": "Alert",
      "description": "shadcn alert as a 1-bit message box.",
      "dependencies": [
        "cn",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/alert.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "card",
      "type": "registry:ui",
      "title": "Card",
      "description": "shadcn card as a raised bevelled pixel panel.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/ui/card.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "accordion",
      "type": "registry:ui",
      "title": "Accordion",
      "description": "shadcn accordion where each item is a raised bevelled box, with beveled chevron toggles and no easing.",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "files": [
        {
          "path": "components/ui/accordion.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "kbd",
      "type": "registry:ui",
      "title": "Kbd",
      "description": "Keyboard keys as small bevelled pixel keycaps, alone or grouped.",
      "files": [
        {
          "path": "components/ui/kbd.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "toggle",
      "type": "registry:ui",
      "title": "Toggle",
      "description": "shadcn toggle as a pixel button that stays sunk while pressed.",
      "files": [
        {
          "path": "components/ui/toggle.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "toggle.on",
          "toggle.off"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "toggle-group",
      "type": "registry:ui",
      "title": "Toggle Group",
      "description": "A row of pixel toggles for one or many choices.",
      "files": [
        {
          "path": "components/ui/toggle-group.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/toggle"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "toggle.on",
          "toggle.off",
          "toggle.select"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "collapsible",
      "type": "registry:ui",
      "title": "Collapsible",
      "description": "Unstyled show and hide region with a trigger, opening in one frame.",
      "files": [
        {
          "path": "components/ui/collapsible.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "popover",
      "type": "registry:ui",
      "title": "Popover",
      "description": "Floating pixel panel with an offset shadow, opened from a trigger.",
      "files": [
        {
          "path": "components/ui/popover.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "hover-card",
      "type": "registry:ui",
      "title": "Hover Card",
      "description": "Pixel preview card that appears on hover, with no fade.",
      "files": [
        {
          "path": "components/ui/hover-card.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "alert-dialog",
      "type": "registry:ui",
      "title": "Alert Dialog",
      "description": "Modal confirmation in the dialog chrome, with action and cancel buttons.",
      "files": [
        {
          "path": "components/ui/alert-dialog.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button"
      ],
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "sheet",
      "type": "registry:ui",
      "title": "Sheet",
      "description": "Edge panel from any side of the screen that opens in one frame.",
      "files": [
        {
          "path": "components/ui/sheet.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "context-menu",
      "type": "registry:ui",
      "title": "Context Menu",
      "description": "Right-click menu with the shared menu look: foreground bar highlight, etched separators, left indicators.",
      "files": [
        {
          "path": "components/ui/context-menu.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "menu.select"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "skeleton",
      "type": "registry:ui",
      "title": "Skeleton",
      "description": "Placeholder block filled with a flowing dithered noise field that steps at 10 fps, shares one timer across every skeleton and holds still under reduced motion.",
      "files": [
        {
          "path": "components/ui/skeleton.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/dither-inks"
      ],
      "dependencies": [
        "cn"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "spinner",
      "type": "registry:ui",
      "title": "Spinner",
      "description": "Pixel spinner that steps at about 10 fps and holds still under reduced motion.",
      "files": [
        {
          "path": "components/ui/spinner.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "avatar",
      "type": "registry:ui",
      "title": "Avatar",
      "description": "Pixel-stepped circle avatar with a 1px ring, a dithered drop shadow, and an image or pixel-font initials.",
      "files": [
        {
          "path": "components/ui/avatar.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "breadcrumb",
      "type": "registry:ui",
      "title": "Breadcrumb",
      "description": "Path trail with pixel chevron separators.",
      "files": [
        {
          "path": "components/ui/breadcrumb.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "table",
      "type": "registry:ui",
      "title": "Table",
      "description": "Data table with pixel rules and a font-pixel header.",
      "files": [
        {
          "path": "components/ui/table.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "pagination",
      "type": "registry:ui",
      "title": "Pagination",
      "description": "Page links built from UI95 buttons with pixel arrows.",
      "files": [
        {
          "path": "components/ui/pagination.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cn"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "button-group",
      "type": "registry:ui",
      "title": "Button Group",
      "description": "Buttons joined edge to edge into one pixel-bordered strip.",
      "files": [
        {
          "path": "components/ui/button-group.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/separator"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "empty",
      "type": "registry:ui",
      "title": "Empty",
      "description": "Empty state with a pixel icon, title, description and actions.",
      "files": [
        {
          "path": "components/ui/empty.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "native-select",
      "type": "registry:ui",
      "title": "Native Select",
      "description": "A native select in the sunken field style with a pixel chevron.",
      "files": [
        {
          "path": "components/ui/native-select.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cn"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "aspect-ratio",
      "type": "registry:ui",
      "title": "Aspect Ratio",
      "description": "Keeps content at a fixed aspect ratio.",
      "files": [
        {
          "path": "components/ui/aspect-ratio.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "item",
      "type": "registry:ui",
      "title": "Item",
      "description": "List row with media, title, description and actions on pixel borders.",
      "files": [
        {
          "path": "components/ui/item.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/separator"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "field",
      "type": "registry:ui",
      "title": "Field",
      "description": "Form field layout: label, control, description and dashed-border errors.",
      "files": [
        {
          "path": "components/ui/field.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/label",
        "@ui95/separator"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "input-group",
      "type": "registry:ui",
      "title": "Input Group",
      "description": "Input or textarea with pixel addons and buttons inside one sunken field.",
      "files": [
        {
          "path": "components/ui/input-group.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/input",
        "@ui95/textarea"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "meta": {
        "sounds": [
          "typewriter.key",
          "typewriter.space",
          "typewriter.return"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "navigation-menu",
      "type": "registry:ui",
      "title": "Navigation Menu",
      "description": "shadcn navigation-menu reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/navigation-menu.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "input-otp",
      "type": "registry:ui",
      "title": "Input Otp",
      "description": "shadcn input-otp reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/input-otp.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cn",
        "input-otp"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "command",
      "type": "registry:ui",
      "title": "Command",
      "description": "shadcn command reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/command.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/dialog",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cmdk",
        "cn"
      ],
      "meta": {
        "sounds": [
          "menu.select",
          "typewriter.key",
          "typewriter.space",
          "typewriter.return"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "resizable",
      "type": "registry:ui",
      "title": "Resizable",
      "description": "shadcn resizable reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/resizable.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn",
        "react-resizable-panels"
      ],
      "meta": {
        "sounds": [
          "slider.tick"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "sidebar",
      "type": "registry:ui",
      "title": "Sidebar",
      "description": "shadcn sidebar reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/sidebar.tsx",
          "type": "registry:ui"
        },
        {
          "path": "hooks/use-mobile.ts",
          "type": "registry:hook"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/input",
        "@ui95/pixel-glyphs",
        "@ui95/separator",
        "@ui95/sheet",
        "@ui95/skeleton",
        "@ui95/tooltip"
      ],
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release",
          "small-button.press",
          "small-button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "calendar",
      "type": "registry:ui",
      "title": "Calendar",
      "description": "shadcn calendar reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/calendar.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cn",
        "react-day-picker"
      ],
      "meta": {
        "sounds": [
          "button.press",
          "button.release",
          "small-button.press",
          "small-button.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "sonner",
      "type": "registry:ui",
      "title": "Sonner",
      "description": "shadcn sonner reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/sonner.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/pixel-glyphs",
        "@ui95/spinner"
      ],
      "dependencies": [
        "next-themes",
        "sonner"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "drawer",
      "type": "registry:ui",
      "title": "Drawer",
      "description": "shadcn drawer reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/drawer.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "dependencies": [
        "cn",
        "vaul"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "carousel",
      "type": "registry:ui",
      "title": "Carousel",
      "description": "shadcn carousel reskinned for UI95.",
      "files": [
        {
          "path": "components/ui/carousel.tsx",
          "type": "registry:ui"
        }
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/pixel-glyphs"
      ],
      "dependencies": [
        "cn",
        "embla-carousel-react"
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "window",
      "type": "registry:block",
      "title": "Window",
      "description": "Draggable retro window with a striped title bar, close button and optional status bar. Drags snap to --pixel.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/pixel-glyphs",
        "@ui95/scroll-area"
      ],
      "files": [
        {
          "path": "components/retro/window.tsx",
          "type": "registry:component",
          "target": "@components/retro/window.tsx"
        },
        {
          "path": "hooks/use-window-drag.ts",
          "type": "registry:hook"
        }
      ],
      "meta": {
        "sounds": [
          "drag.pickup",
          "drag.drop",
          "drag.friction"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "error-dialog",
      "type": "registry:block",
      "title": "Error dialog",
      "description": "Stackable error dialogs that cascade diagonally.",
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/dialog",
        "@ui95/pixel-glyphs"
      ],
      "files": [
        {
          "path": "components/retro/error-dialog.tsx",
          "type": "registry:component",
          "target": "@components/retro/error-dialog.tsx"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "terminal",
      "type": "registry:block",
      "title": "Terminal",
      "description": "Terminal screen that types commands after a prompt, prints output and blinks a block cursor.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [
        "@ui95/theme"
      ],
      "files": [
        {
          "path": "components/retro/terminal.tsx",
          "type": "registry:component",
          "target": "@components/retro/terminal.tsx"
        }
      ],
      "categories": [
        "ui"
      ]
    },
    {
      "name": "taskbar",
      "type": "registry:block",
      "title": "Taskbar",
      "description": "Beveled taskbar with a Start button, a start menu built on dropdown-menu, a task area and a clock slot.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [
        "@ui95/theme",
        "@ui95/button",
        "@ui95/dropdown-menu"
      ],
      "files": [
        {
          "path": "components/retro/taskbar.tsx",
          "type": "registry:component",
          "target": "@components/retro/taskbar.tsx"
        }
      ],
      "meta": {
        "sounds": [
          "taskbar.press",
          "taskbar.release"
        ]
      },
      "categories": [
        "ui"
      ]
    },
    {
      "name": "crt-screen",
      "type": "registry:block",
      "title": "CRT screen",
      "description": "A realistic CRT filter to really take your UI back in time. Fully customizable.",
      "docs": "Scoped is the default: the effect covers the box and its children, and the overlay never takes the pointer. Pass fullscreen to lay it over the whole viewport instead; curvature, aberration and bloom then filter the whole document, which costs more on large pages. Put padding and backgrounds on the children, not on CrtScreen, so the warp and the overlay share one box. Scanlines and grain are alpha black and white at device resolution and follow the barrel curve. Under curvature, clicks land at the undistorted position of the element. Portals opened from inside a scoped CrtScreen (dialogs, menus, toasts) mount on the body and escape the effect; use fullscreen to cover them. Reduced motion freezes the grain and turns flicker off.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [
        "@ui95/shader-mount",
        "@ui95/use-prefers-reduced-motion"
      ],
      "files": [
        {
          "path": "lib/shaders/crt.ts",
          "type": "registry:lib",
          "target": "@lib/shaders/crt.ts"
        },
        {
          "path": "lib/crt/warp-filter.ts",
          "type": "registry:lib",
          "target": "@lib/crt/warp-filter.ts"
        },
        {
          "path": "components/retro/crt-screen.tsx",
          "type": "registry:component",
          "target": "@components/retro/crt-screen.tsx"
        }
      ],
      "categories": [
        "shared"
      ]
    }
  ]
}
