{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "intelligence-glow",
  "title": "Intelligence Glow",
  "description": "A slow light around the screen edge while the assistant listens or thinks, visible from anywhere on the page.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils",
    "https://miseui.junsu4621.workers.dev/r/motion.json"
  ],
  "files": [
    {
      "path": "registry/miseui/ui/intelligence-glow.tsx",
      "content": "import type * as React from \"react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport { SPRING_DEFAULT, clampUnit } from \"@/registry/miseui/lib/motion\"\nimport { cn } from \"@/registry/miseui/lib/utils\"\n\nconst DEFAULT_INTENSITY = 0.6\n/** One slow lap: alive enough to notice, slow enough never to pull the eye off the content. */\nconst LAP_SECONDS = 10\n/** Band width grows 1.5 px to 5 px with intensity; the haze is three bands wide and blurred. */\nconst MIN_BAND_PX = 1.5\nconst BAND_RANGE_PX = 3.5\nconst HAZE_BAND_FACTOR = 3\nconst MIN_BLUR_PX = 8\nconst BLUR_RANGE_PX = 24\n/** The band is always clearly there; the haze is what intensity mostly buys. */\nconst BAND_BASE_OPACITY = 0.5\nconst HAZE_MAX_OPACITY = 0.7\n/** A square 1.5× the longer side covers the ring at every angle (√2 would be exact). */\nconst COVER_FACTOR = 1.5\n\n/** Mise and two lightness neighbours mixed from tokens, so the light stays one hue, never a rainbow. Ends where it starts. */\nconst GLOW_GRADIENT = [\n  \"conic-gradient(from 0deg, var(--mise)\",\n  \"color-mix(in oklch, var(--mise) 70%, var(--background))\",\n  \"var(--mise)\",\n  \"color-mix(in oklch, var(--mise) 70%, var(--foreground))\",\n  \"var(--mise))\",\n].join(\", \")\n/** Content box cut out of the border box leaves only the padding ring painted. */\nconst RING_MASK = \"linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0)\"\n\n/** motion.div owns these; the same names on a plain div would not type-check against it. */\ntype DivProps = Omit<React.ComponentProps<\"div\">, \"style\" | \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\">\n\ninterface IntelligenceGlowProps extends DivProps {\n  /** Shown while the assistant is listening or thinking. Fades in and out. */\n  active?: boolean\n  /** 0..1, how much light. Values outside the range are clamped. */\n  intensity?: number\n  /** False: the screen edges (fixed). True: the edges of the nearest positioned parent. */\n  inset?: boolean\n  style?: React.CSSProperties\n}\n\nfunction IntelligenceGlow({\n  active = false,\n  intensity = DEFAULT_INTENSITY,\n  inset = false,\n  className,\n  style,\n  ...props\n}: IntelligenceGlowProps) {\n  const reduceMotion = useReducedMotion()\n  const level = clampUnit(intensity)\n  const bandPx = MIN_BAND_PX + BAND_RANGE_PX * level\n  const blurPx = MIN_BLUR_PX + BLUR_RANGE_PX * level\n\n  return (\n    <AnimatePresence>\n      {active ? (\n        <motion.div\n          role=\"presentation\"\n          aria-hidden=\"true\"\n          data-slot=\"intelligence-glow\"\n          data-active=\"true\"\n          data-reduced={reduceMotion ? \"true\" : \"false\"}\n          className={cn(\n            \"pointer-events-none inset-0 overflow-hidden\",\n            inset ? \"absolute rounded-[inherit]\" : \"fixed z-50\",\n            className,\n          )}\n          style={{ ...style, \"--glow-intensity\": `${level}`, \"--glow-blur\": `${blurPx}px` } as React.CSSProperties}\n          initial={{ opacity: 0 }}\n          animate={{ opacity: 1 }}\n          exit={{ opacity: 0 }}\n          transition={SPRING_DEFAULT}\n          {...props}\n        >\n          <GlowRing\n            width={bandPx * HAZE_BAND_FACTOR}\n            opacity={HAZE_MAX_OPACITY * level}\n            spin={!reduceMotion}\n            className=\"blur-(--glow-blur) [@media(prefers-reduced-transparency:reduce)]:blur-none\"\n          />\n          <GlowRing width={bandPx} opacity={BAND_BASE_OPACITY + (1 - BAND_BASE_OPACITY) * level} spin={!reduceMotion} />\n        </motion.div>\n      ) : null}\n    </AnimatePresence>\n  )\n}\n\ninterface GlowRingProps {\n  width: number\n  opacity: number\n  spin: boolean\n  className?: string\n}\n\n/**\n * Blur sits on the outer element and the mask on the inner one. Filters apply before masks on the\n * same element, so blurring the masked element itself would leave a hard-edged ring.\n */\nfunction GlowRing({ width, opacity, spin, className }: GlowRingProps) {\n  return (\n    <div className={cn(\"absolute inset-0 rounded-[inherit]\", className)} style={{ opacity }}>\n      <div\n        className=\"absolute inset-0 overflow-hidden rounded-[inherit] [container-type:size]\"\n        style={{ padding: width, mask: RING_MASK, maskComposite: \"exclude\" } as React.CSSProperties}\n      >\n        <div\n          data-testid=\"glow-spin\"\n          className={cn(\"absolute top-1/2 left-1/2 aspect-square -translate-x-1/2 -translate-y-1/2\", spin && \"animate-spin\")}\n          style={{\n            width: `calc(max(100cqw, 100cqh) * ${COVER_FACTOR})`,\n            backgroundImage: GLOW_GRADIENT,\n            animationDuration: `${LAP_SECONDS}s`,\n          }}\n        />\n      </div>\n    </div>\n  )\n}\n\nexport { IntelligenceGlow, type IntelligenceGlowProps }\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "effects"
  ],
  "type": "registry:ui"
}