{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "night-owl",
  "type": "registry:component",
  "title": "Night Owl",
  "description": "An owl on a branch that follows your cursor and tilts its head at you. Wide awake under the moon in dark mode, heavy-lidded and snoozing in light mode.",
  "categories": [
    "illustration",
    "Characters"
  ],
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/devl/night-owl.tsx",
      "type": "registry:component",
      "content": "\"use client\";\n\nimport {\n  type AnimationPlaybackControls,\n  animate,\n  AnimatePresence,\n  motion,\n  type MotionValue,\n  useInView,\n  useMotionValue,\n  useReducedMotion,\n  useSpring,\n  useTransform,\n} from \"motion/react\";\nimport { type PointerEvent, type RefObject, useEffect, useId, useRef, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type NightOwlHue = \"violet\" | \"indigo\" | \"sky\" | \"teal\" | \"amber\" | \"orange\" | \"rose\" | \"emerald\";\nexport type NightOwlMode = \"auto\" | \"awake\" | \"sleepy\";\n\nconst hues: Record<NightOwlHue, string> = {\n  violet:\n    \"[--hue-hi:var(--color-violet-300)] [--hue:var(--color-violet-400)] [--hue-deep:var(--color-violet-600)] [--soft:var(--color-violet-100)] [--ink:var(--color-violet-950)]\",\n  indigo:\n    \"[--hue-hi:var(--color-indigo-300)] [--hue:var(--color-indigo-400)] [--hue-deep:var(--color-indigo-600)] [--soft:var(--color-indigo-100)] [--ink:var(--color-indigo-950)]\",\n  sky: \"[--hue-hi:var(--color-sky-300)] [--hue:var(--color-sky-400)] [--hue-deep:var(--color-sky-600)] [--soft:var(--color-sky-100)] [--ink:var(--color-sky-950)]\",\n  teal: \"[--hue-hi:var(--color-teal-300)] [--hue:var(--color-teal-400)] [--hue-deep:var(--color-teal-600)] [--soft:var(--color-teal-100)] [--ink:var(--color-teal-950)]\",\n  amber:\n    \"[--hue-hi:var(--color-amber-300)] [--hue:var(--color-amber-400)] [--hue-deep:var(--color-amber-600)] [--soft:var(--color-amber-100)] [--ink:var(--color-amber-950)]\",\n  orange:\n    \"[--hue-hi:var(--color-orange-300)] [--hue:var(--color-orange-400)] [--hue-deep:var(--color-orange-600)] [--soft:var(--color-orange-100)] [--ink:var(--color-orange-950)]\",\n  rose: \"[--hue-hi:var(--color-rose-300)] [--hue:var(--color-rose-400)] [--hue-deep:var(--color-rose-600)] [--soft:var(--color-rose-100)] [--ink:var(--color-rose-950)]\",\n  emerald:\n    \"[--hue-hi:var(--color-emerald-300)] [--hue:var(--color-emerald-400)] [--hue-deep:var(--color-emerald-600)] [--soft:var(--color-emerald-100)] [--ink:var(--color-emerald-950)]\",\n};\n\nexport interface NightOwlProps {\n  name?: string;\n  hue?: NightOwlHue;\n  mode?: NightOwlMode;\n  awakeTitle?: string;\n  awakeDescription?: string;\n  sleepyTitle?: string;\n  sleepyDescription?: string;\n  onHoot?: () => void;\n  className?: string;\n}\n\nconst VB = { x: 20, y: 24, w: 360, h: 212 };\nconst FACE = { x: 200, y: 130 };\nconst EYE_R = 16;\nconst LID = 36;\n\nconst stars = [\n  { x: 70, y: 58, s: 1, delay: 0 },\n  { x: 112, y: 96, s: 0.65, delay: 1.1 },\n  { x: 254, y: 46, s: 0.7, delay: 0.5 },\n  { x: 290, y: 112, s: 0.8, delay: 1.7 },\n  { x: 356, y: 128, s: 0.6, delay: 0.8 },\n  { x: 48, y: 136, s: 0.55, delay: 2.2 },\n];\n\nconst zs = [\n  { size: 12, x: 260, y: 96, delay: 0 },\n  { size: 16, x: 272, y: 80, delay: 0.9 },\n  { size: 20, x: 282, y: 64, delay: 1.8 },\n];\n\nconst chevrons = [\n  [188, 168],\n  [212, 168],\n  [176, 182],\n  [200, 182],\n  [224, 182],\n  [188, 196],\n  [212, 196],\n];\n\nconst STAR = \"M0 -6 Q1 -1 6 0 Q1 1 0 6 Q-1 1 -6 0 Q-1 -1 0 -6 Z\";\n\nfunction useCalmMotion() {\n  const prefers = useReducedMotion();\n  const [mounted, setMounted] = useState(false);\n  useEffect(() => setMounted(true), []);\n  return mounted && !!prefers;\n}\n\nfunction useBlink(active: boolean, slow: boolean) {\n  const open = useMotionValue(1);\n  useEffect(() => {\n    if (!active) {\n      open.set(1);\n      return;\n    }\n    let timer: ReturnType<typeof setTimeout>;\n    let blink: AnimationPlaybackControls | undefined;\n    const schedule = () => {\n      timer = setTimeout(\n        () => {\n          const twice = !slow && Math.random() < 0.2;\n          blink = animate(open, twice ? [1, 0, 1, 0, 1] : [1, 0, 1], {\n            duration: slow ? 0.9 : twice ? 0.42 : 0.2,\n            ease: \"easeInOut\",\n            times: twice ? [0, 0.18, 0.5, 0.68, 1] : slow ? [0, 0.45, 1] : [0, 0.38, 1],\n          });\n          schedule();\n        },\n        slow ? 3200 + Math.random() * 3000 : 2400 + Math.random() * 3600,\n      );\n    };\n    schedule();\n    return () => {\n      clearTimeout(timer);\n      blink?.stop();\n    };\n  }, [active, slow, open]);\n  return open;\n}\n\nfunction useDarkAncestor(ref: RefObject<HTMLElement | null>) {\n  const [dark, setDark] = useState<boolean | null>(null);\n  useEffect(() => {\n    const el = ref.current;\n    if (!el) return;\n    const read = () => setDark(!!el.closest(\".dark\"));\n    read();\n    const observer = new MutationObserver(read);\n    observer.observe(document.documentElement, { attributeFilter: [\"class\"], attributes: true });\n    observer.observe(document.body, { attributeFilter: [\"class\"], attributes: true });\n    return () => observer.disconnect();\n  }, [ref]);\n  return dark;\n}\n\nfunction Eye({\n  cx,\n  uid,\n  lookX,\n  lookY,\n  cover,\n}: {\n  cx: number;\n  uid: string;\n  lookX: MotionValue<number>;\n  lookY: MotionValue<number>;\n  cover: MotionValue<number>;\n}) {\n  const id = `${uid}-eye-${cx}`;\n  return (\n    <g>\n      <clipPath id={id}>\n        <circle cx={cx} cy={FACE.y} r={EYE_R} />\n      </clipPath>\n      <circle className=\"fill-white\" cx={cx} cy={FACE.y} r={EYE_R} />\n      <g clipPath={`url(#${id})`}>\n        <motion.g style={{ x: lookX, y: lookY }}>\n          <circle className=\"fill-(--ink)\" cx={cx} cy={FACE.y} r={8.5} />\n          <circle className=\"fill-white\" cx={cx - 3} cy={FACE.y - 3.2} r={2.6} />\n        </motion.g>\n        <motion.g style={{ y: cover }}>\n          <path\n            className=\"fill-(--hue)\"\n            d={`M${cx - EYE_R - 2} ${FACE.y - EYE_R - LID} H${cx + EYE_R + 2} V${FACE.y - EYE_R} Q${cx} ${FACE.y - EYE_R + 7} ${cx - EYE_R - 2} ${FACE.y - EYE_R} Z`}\n          />\n          <path\n            className=\"fill-none stroke-(--hue-deep)\"\n            d={`M${cx - EYE_R - 2} ${FACE.y - EYE_R} Q${cx} ${FACE.y - EYE_R + 7} ${cx + EYE_R + 2} ${FACE.y - EYE_R}`}\n            strokeLinecap=\"round\"\n            strokeWidth={2.5}\n          />\n        </motion.g>\n      </g>\n    </g>\n  );\n}\n\nexport function NightOwl({\n  name = \"Ollie\",\n  hue = \"violet\",\n  mode = \"auto\",\n  awakeTitle = \"Working late?\",\n  awakeDescription = \"The night shift is better with company.\",\n  sleepyTitle,\n  sleepyDescription = \"Owls nap through the day. Switch to dark mode to wake him.\",\n  onHoot,\n  className,\n}: NightOwlProps) {\n  const uid = useId().replace(/:/g, \"\");\n  const reduce = useCalmMotion();\n  const root = useRef<HTMLDivElement>(null);\n  const svg = useRef<SVGSVGElement>(null);\n  const inView = useInView(root);\n  const live = inView && !reduce;\n  const dark = useDarkAncestor(root);\n  const awake = mode === \"awake\" || (mode === \"auto\" && dark !== false);\n  const [tracking, setTracking] = useState(false);\n  const [hoot, setHoot] = useState(0);\n  const [startled, setStartled] = useState(false);\n  const alert = awake || startled;\n\n  const gazeX = useMotionValue(0);\n  const gazeY = useMotionValue(0);\n  const lookX = useSpring(gazeX, { stiffness: 200, damping: 24, mass: 0.7 });\n  const lookY = useSpring(gazeY, { stiffness: 200, damping: 24, mass: 0.7 });\n  const pupilX = useTransform(lookX, (v) => v * 6.5);\n  const pupilY = useTransform(lookY, (v) => v * 5.5);\n\n  const tilt = useMotionValue(0);\n  const droop = useMotionValue(0);\n  const headRotate = useTransform([tilt, lookX] as const, ([t, l]: number[]) => t + l * 5);\n  const heaviness = useMotionValue(0);\n  const open = useBlink(live, !alert);\n  const cover = useTransform([heaviness, open] as const, ([h, o]: number[]) => (h + (1 - h) * (1 - o)) * (EYE_R * 2 + 2));\n  const puff = useMotionValue(1);\n  const first = useRef(true);\n  const startleTimer = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n  useEffect(() => () => clearTimeout(startleTimer.current), []);\n\n  useEffect(() => {\n    if (mode === \"auto\" && dark === null) return;\n    const target = alert ? 0 : 0.58;\n    if (first.current || reduce) {\n      first.current = false;\n      heaviness.set(target);\n      droop.set(alert ? 0 : 1);\n      return;\n    }\n    const lids = animate(heaviness, target, { duration: alert ? 0.35 : 1.4, ease: [0.65, 0, 0.35, 1] });\n    const head = animate(droop, alert ? 0 : 1, { duration: alert ? 0.4 : 1.6, ease: [0.65, 0, 0.35, 1] });\n    return () => {\n      lids.stop();\n      head.stop();\n    };\n  }, [alert, dark, mode, reduce, heaviness, droop]);\n\n  useEffect(() => {\n    if (!live || !awake) {\n      animate(tilt, 0, { duration: 0.8, ease: [0.65, 0, 0.35, 1] });\n      return;\n    }\n    let timer: ReturnType<typeof setTimeout>;\n    let move: AnimationPlaybackControls | undefined;\n    const curious = () => {\n      const side = Math.random() < 0.5 ? -1 : 1;\n      move = animate(tilt, side * (9 + Math.random() * 6), { duration: 1.1, ease: [0.65, 0, 0.35, 1] });\n      timer = setTimeout(() => {\n        move = animate(tilt, 0, { duration: 0.9, ease: [0.65, 0, 0.35, 1] });\n        timer = setTimeout(curious, 3200 + Math.random() * 3600);\n      }, 1500 + Math.random() * 900);\n    };\n    timer = setTimeout(curious, 2200);\n    return () => {\n      clearTimeout(timer);\n      move?.stop();\n    };\n  }, [live, awake, tilt]);\n\n  useEffect(() => {\n    if (!live || tracking) {\n      if (!live) {\n        gazeX.set(0);\n        gazeY.set(0);\n      }\n      return;\n    }\n    let timer: ReturnType<typeof setTimeout>;\n    const look = () => {\n      const centre = Math.random() < 0.4;\n      gazeX.set(centre ? 0 : (Math.random() * 2 - 1) * 0.8);\n      gazeY.set(centre ? 0 : (Math.random() * 2 - 1) * 0.5);\n      timer = setTimeout(look, awake ? 1500 + Math.random() * 2500 : 3000 + Math.random() * 3000);\n    };\n    timer = setTimeout(look, 900);\n    return () => clearTimeout(timer);\n  }, [live, tracking, awake, gazeX, gazeY]);\n\n  const follow = (e: PointerEvent<HTMLDivElement>) => {\n    if (e.pointerType === \"touch\" || reduce) return;\n    const box = svg.current?.getBoundingClientRect();\n    if (!box?.width) return;\n    const unit = box.width / VB.w;\n    const dx = (e.clientX - box.left) / unit + VB.x - FACE.x;\n    const dy = (e.clientY - box.top) / unit + VB.y - FACE.y;\n    const reach = Math.hypot(dx, dy, 70);\n    gazeX.set(dx / reach);\n    gazeY.set(dy / reach);\n    setTracking(true);\n  };\n\n  const release = () => {\n    setTracking(false);\n    gazeX.set(0);\n    gazeY.set(0);\n  };\n\n  const hootNow = () => {\n    setHoot((h) => h + 1);\n    setStartled(true);\n    clearTimeout(startleTimer.current);\n    startleTimer.current = setTimeout(() => setStartled(false), 1800);\n    onHoot?.();\n    if (!reduce) animate(puff, [1, 1.06, 0.98, 1], { duration: 0.55, ease: \"easeOut\", times: [0, 0.35, 0.7, 1] });\n  };\n\n  const headY = useTransform(droop, (d) => d * 4);\n  const headDroop = useTransform([headRotate, droop] as const, ([r, d]: number[]) => r + d * 7);\n  const sky = (night: boolean) =>\n    mode === \"auto\" ? (night ? \"opacity-0 dark:opacity-100\" : \"opacity-100 dark:opacity-0\") : night === awake ? \"opacity-100\" : \"opacity-0\";\n  const title = awake ? awakeTitle : (sleepyTitle ?? `${name} is fast asleep`);\n  const description = awake ? awakeDescription : sleepyDescription;\n\n  return (\n    <div\n      ref={root}\n      className={cn(\n        \"relative w-full max-w-[420px] overflow-hidden rounded-2xl border bg-card p-4 shadow-xs/5 sm:p-6\",\n        hues[hue],\n        className,\n      )}\n      onPointerLeave={release}\n      onPointerMove={follow}\n    >\n      <div\n        aria-hidden\n        className=\"dot-grid pointer-events-none absolute inset-0 opacity-50 [mask-image:radial-gradient(closest-side,black,transparent)]\"\n      />\n      <button\n        aria-label={`${name} the owl, ${awake ? \"wide awake\" : \"asleep\"}. Give a hoot`}\n        className=\"relative mx-auto block aspect-[90/53] w-full max-w-[380px] cursor-pointer rounded-xl outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n        onClick={hootNow}\n        type=\"button\"\n      >\n        <svg aria-hidden className=\"absolute inset-0 size-full overflow-visible\" ref={svg} viewBox={`${VB.x} ${VB.y} ${VB.w} ${VB.h}`}>\n          <defs>\n            <mask id={`${uid}-moon`}>\n              <rect fill=\"white\" height={60} width={60} x={306} y={28} />\n              <circle cx={345} cy={50} fill=\"black\" r={17} />\n            </mask>\n          </defs>\n\n          <g className={cn(\"transition-opacity duration-700\", sky(true))}>\n            <circle className=\"fill-amber-200\" cx={336} cy={58} mask={`url(#${uid}-moon)`} r={20} />\n            {stars.map((s) => (\n              <g key={`${s.x}-${s.y}`} transform={`translate(${s.x} ${s.y}) scale(${s.s})`}>\n                <motion.path\n                  animate={live ? { opacity: [1, 0.3, 1], scale: [1, 0.7, 1] } : { opacity: 1, scale: 1 }}\n                  className=\"fill-amber-200\"\n                  d={STAR}\n                  transition={live ? { delay: s.delay, duration: 2.6, ease: \"easeInOut\", repeat: Number.POSITIVE_INFINITY } : { duration: 0.3 }}\n                />\n              </g>\n            ))}\n          </g>\n\n          <g className={cn(\"transition-opacity duration-700\", sky(false))}>\n            <motion.g\n              animate={live ? { rotate: 360 } : { rotate: 0 }}\n              className=\"stroke-amber-400\"\n              strokeLinecap=\"round\"\n              strokeWidth={3}\n              style={{ originX: \"336px\", originY: \"58px\", transformBox: \"view-box\" }}\n              transition={live ? { duration: 40, ease: \"linear\", repeat: Number.POSITIVE_INFINITY } : { duration: 0 }}\n            >\n              {[0, 45, 90, 135, 180, 225, 270, 315].map((a) => (\n                <line key={a} transform={`rotate(${a} 336 58)`} x1={336} x2={336} y1={35} y2={30} />\n              ))}\n            </motion.g>\n            <circle className=\"fill-amber-300\" cx={336} cy={58} r={15} />\n            <path className=\"fill-foreground/[0.06]\" d=\"M280 106 a10 10 0 0 1 18 -6 a12 12 0 0 1 22 4 a8 8 0 0 1 2 16 h-40 a7 7 0 0 1 -2 -14 Z\" />\n          </g>\n\n          <path\n            className=\"fill-none stroke-amber-900/85 dark:stroke-amber-800\"\n            d=\"M28 218 Q 200 197 372 223\"\n            strokeLinecap=\"round\"\n            strokeWidth={10}\n          />\n          <path className=\"fill-none stroke-amber-900/85 dark:stroke-amber-800\" d=\"M300 211 q 14 -14 34 -18\" strokeLinecap=\"round\" strokeWidth={5} />\n          <path className=\"fill-none stroke-amber-900/85 dark:stroke-amber-800\" d=\"M88 210 q -8 -12 -24 -18\" strokeLinecap=\"round\" strokeWidth={5} />\n          <g className=\"fill-emerald-500 dark:fill-emerald-400\">\n            <ellipse cx={340} cy={190} rx={11} ry={5.5} transform=\"rotate(-20 340 190)\" />\n            <ellipse cx={318} cy={196} rx={9} ry={4.5} transform=\"rotate(-50 318 196)\" />\n            <ellipse cx={58} cy={190} rx={11} ry={5.5} transform=\"rotate(25 58 190)\" />\n            <ellipse cx={76} cy={196} rx={8} ry={4} transform=\"rotate(60 76 196)\" />\n          </g>\n\n          <motion.g style={{ originX: \"200px\", originY: \"208px\", scale: puff, transformBox: \"view-box\" }}>\n            <motion.g\n              animate={live ? { scaleY: [1, 1.018, 1] } : { scaleY: 1 }}\n              style={{ originX: \"200px\", originY: \"208px\", transformBox: \"view-box\" }}\n              transition={live ? { duration: awake ? 3.2 : 4.6, ease: \"easeInOut\", repeat: Number.POSITIVE_INFINITY } : { duration: 0.4 }}\n            >\n              <motion.g style={{ rotate: headDroop, y: headY, originX: \"200px\", originY: \"150px\", transformBox: \"view-box\" }}>\n                <path className=\"fill-(--hue) stroke-(--hue)\" d=\"M160 112 L150 78 L184 98 Z\" strokeLinejoin=\"round\" strokeWidth={6} />\n                <path className=\"fill-(--hue) stroke-(--hue)\" d=\"M240 112 L250 78 L216 98 Z\" strokeLinejoin=\"round\" strokeWidth={6} />\n              </motion.g>\n\n              <path\n                className=\"fill-(--hue)\"\n                d=\"M200 90 C 238 90 256 116 256 150 C 256 186 234 210 200 210 C 166 210 144 186 144 150 C 144 116 162 90 200 90 Z\"\n              />\n              <path className=\"fill-none stroke-white/30\" d=\"M160 116 q8 -16 24 -20\" strokeLinecap=\"round\" strokeWidth={5} />\n              <ellipse className=\"fill-(--soft)\" cx={200} cy={180} rx={34} ry={27} />\n              <g className=\"fill-none stroke-(--hue)/60\" strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}>\n                {chevrons.map(([x, y]) => (\n                  <path d={`M${x - 4} ${y - 2} L${x} ${y + 2} L${x + 4} ${y - 2}`} key={`${x}-${y}`} />\n                ))}\n              </g>\n\n              <motion.g\n                animate={hoot > 0 && !reduce ? { rotate: [0, -16, 0, -10, 0] } : { rotate: 0 }}\n                key={`wl-${hoot}`}\n                style={{ originX: \"156px\", originY: \"140px\", transformBox: \"view-box\" }}\n                transition={{ duration: 0.55, ease: \"easeOut\" }}\n              >\n                <ellipse className=\"fill-(--hue-deep)\" cx={154} cy={166} rx={12} ry={29} transform=\"rotate(12 154 166)\" />\n              </motion.g>\n              <motion.g\n                animate={hoot > 0 && !reduce ? { rotate: [0, 16, 0, 10, 0] } : { rotate: 0 }}\n                key={`wr-${hoot}`}\n                style={{ originX: \"244px\", originY: \"140px\", transformBox: \"view-box\" }}\n                transition={{ duration: 0.55, ease: \"easeOut\" }}\n              >\n                <ellipse className=\"fill-(--hue-deep)\" cx={246} cy={166} rx={12} ry={29} transform=\"rotate(-12 246 166)\" />\n              </motion.g>\n\n              <motion.g style={{ rotate: headDroop, y: headY, originX: \"200px\", originY: \"150px\", transformBox: \"view-box\" }}>\n                <circle className=\"fill-(--soft)\" cx={180} cy={FACE.y} r={24} />\n                <circle className=\"fill-(--soft)\" cx={220} cy={FACE.y} r={24} />\n                <Eye cover={cover} cx={180} lookX={pupilX} lookY={pupilY} uid={uid} />\n                <Eye cover={cover} cx={220} lookX={pupilX} lookY={pupilY} uid={uid} />\n                <path className=\"fill-amber-400 stroke-amber-400\" d=\"M200 140 L207 149 L200 159 L193 149 Z\" strokeLinejoin=\"round\" strokeWidth={2} />\n                <path className=\"fill-white/40\" d=\"M200 141.5 L204.5 148 L200 148 Z\" />\n              </motion.g>\n            </motion.g>\n          </motion.g>\n\n          <g className=\"fill-amber-400\">\n            {[-1, 1].map((side) =>\n              [-6, 0, 6].map((dx) => <circle cx={200 + side * 16 + dx} cy={208} key={`${side}-${dx}`} r={3.6} />),\n            )}\n          </g>\n\n          <AnimatePresence>\n            {hoot > 0 && startled && (\n              <motion.text\n                animate={reduce ? { opacity: 1 } : { opacity: [0, 1, 1, 0], y: [0, -8, -14, -22] }}\n                className=\"fill-(--hue-deep) font-semibold dark:fill-(--hue-hi)\"\n                exit={{ opacity: 0 }}\n                fontSize={15}\n                initial={{ opacity: 0 }}\n                key={`hoo-${hoot}`}\n                transition={reduce ? { duration: 0.2 } : { duration: 1.4, ease: \"easeOut\", times: [0, 0.2, 0.6, 1] }}\n                textAnchor=\"end\"\n                x={142}\n                y={112}\n              >\n                hoo!\n              </motion.text>\n            )}\n          </AnimatePresence>\n\n          {!alert &&\n            zs.map((z) => (\n              <motion.text\n                animate={\n                  live\n                    ? { opacity: [0, 1, 1, 0], x: [0, 6, 10, 14], y: [6, -4, -12, -20] }\n                    : { opacity: 1, x: 0, y: 0 }\n                }\n                className=\"fill-(--hue-deep) font-semibold dark:fill-(--hue-hi)\"\n                fontSize={z.size}\n                initial={{ opacity: 0 }}\n                key={z.x}\n                transition={\n                  live\n                    ? { delay: 1 + z.delay, duration: 2.7, ease: \"easeOut\", repeat: Number.POSITIVE_INFINITY, times: [0, 0.25, 0.7, 1] }\n                    : { duration: 0.3 }\n                }\n                x={z.x}\n                y={z.y}\n              >\n                z\n              </motion.text>\n            ))}\n        </svg>\n      </button>\n\n      <div className=\"relative mt-3 text-center\" aria-live=\"polite\">\n        <p className=\"text-balance font-medium text-foreground text-sm\">{title}</p>\n        <p className=\"mx-auto mt-1 min-h-8 max-w-[34ch] text-pretty text-muted-foreground text-xs\">{description}</p>\n      </div>\n    </div>\n  );\n}\n"
    }
  ]
}