{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "claude-thinking",
  "title": "Claude Thinking",
  "description": "The working line — pulsing sparkle, rotating verb, elapsed/interrupt hint — as an aria-live status region.",
  "files": [
    {
      "path": "registry/brainless/claude/claude-thinking.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\n/**\n * ClaudeThinking — Claude Code's \"working\" line.\n *\n * A pulsing sparkle glyph, a whimsical verb, and a live elapsed / interrupt\n * hint. The verb carries Claude's understated shimmer: a lighter highlight\n * drifts across the terracotta word like a gradient wave (done with\n * background-clip: text so the DOM text stays selectable and announced). The\n * whole line is a polite live region for screen readers.\n */\n// Captured cycle from claude/thinking frames: · ✢ ✳ ✶ ✻ ✽ ✻ ✶ ✳ ✢\nconst GLYPHS = [\"·\", \"✢\", \"✳\", \"✶\", \"✻\", \"✽\", \"✻\", \"✶\", \"✳\", \"✢\"];\nconst VERBS = [\n  \"Thinking\",\n  \"Levitating\",\n  \"Schlepping\",\n  \"Herding\",\n  \"Percolating\",\n  \"Noodling\",\n  \"Conjuring\",\n];\n\nconst CLAUDE = \"#cd694a\"; // terracotta base\nconst HILITE = \"#e79475\"; // the highlight the wave carries\nconst DIM = \"#7d7d7d\";\n\nexport function ClaudeThinking({\n  running = true,\n  verbs = VERBS,\n  showTokens = true,\n  className,\n}: {\n  running?: boolean;\n  verbs?: string[];\n  showTokens?: boolean;\n  className?: string;\n}) {\n  const prefersReduced = usePrefersReducedMotion();\n  const [glyph, setGlyph] = React.useState(0);\n  const [verbIdx, setVerbIdx] = React.useState(0);\n  const [secs, setSecs] = React.useState(0);\n\n  React.useEffect(() => {\n    if (!running || prefersReduced) return;\n    const id = setInterval(() => setGlyph((g) => (g + 1) % GLYPHS.length), 110);\n    return () => clearInterval(id);\n  }, [running, prefersReduced]);\n\n  React.useEffect(() => {\n    if (!running) return;\n    const id = setInterval(() => setSecs((s) => s + 1), 1000);\n    return () => clearInterval(id);\n  }, [running]);\n\n  React.useEffect(() => {\n    if (!running) return;\n    // Verbs change slowly, like the real thing — not every second.\n    const id = setInterval(() => setVerbIdx((v) => (v + 1) % verbs.length), 5200);\n    return () => clearInterval(id);\n  }, [running, verbs.length]);\n\n  if (!running) return null;\n\n  const verb = verbs[verbIdx % verbs.length];\n  const tokens = showTokens ? ` · ↑ ${Math.max(0, secs * 137)} tokens` : \"\";\n\n  return (\n    <div\n      role=\"status\"\n      aria-live=\"polite\"\n      className={className}\n      style={{\n        fontFamily: \"var(--font-geist-mono, ui-monospace, monospace)\",\n        fontSize: 13,\n        display: \"flex\",\n        alignItems: \"center\",\n        gap: 8,\n      }}\n    >\n      <style>{`\n        .cw-verb {\n          background-image: linear-gradient(100deg, ${CLAUDE} 43%, ${HILITE} 50%, ${CLAUDE} 57%);\n          background-size: 200% 100%;\n          -webkit-background-clip: text;\n          background-clip: text;\n          color: transparent;\n          -webkit-text-fill-color: transparent;\n          animation: cw-shine 2.8s linear infinite;\n        }\n        @keyframes cw-shine {\n          from { background-position: 100% 0; }\n          to   { background-position: -100% 0; }\n        }\n        @media (prefers-reduced-motion: reduce) {\n          .cw-verb {\n            animation: none;\n            background-image: none;\n            color: ${CLAUDE};\n            -webkit-text-fill-color: ${CLAUDE};\n          }\n        }\n      `}</style>\n      <span aria-hidden style={{ color: CLAUDE, width: \"1ch\", display: \"inline-block\" }}>\n        {prefersReduced ? \"✳\" : GLYPHS[glyph]}\n      </span>\n      <span className=\"cw-verb\">{verb}…</span>\n      <span style={{ color: DIM }}>\n        ({secs}s{tokens} · esc to interrupt)\n      </span>\n    </div>\n  );\n}\n\nfunction usePrefersReducedMotion() {\n  const [reduced, setReduced] = React.useState(false);\n  React.useEffect(() => {\n    const mq = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n    setReduced(mq.matches);\n    const on = () => setReduced(mq.matches);\n    mq.addEventListener(\"change\", on);\n    return () => mq.removeEventListener(\"change\", on);\n  }, []);\n  return reduced;\n}\n",
      "type": "registry:ui",
      "target": "components/brainless/claude/claude-thinking.tsx"
    }
  ],
  "type": "registry:ui"
}