{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "circular-text",
  "title": "Circular Text",
  "author": "AlgorizeTech",
  "description": "Words set on a circle, turning slowly, with room in the middle for a mark, a play button or a link. Use it for video badges, stamps and 'see the work' links.",
  "dependencies": [],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/components/custom/blocks/CircularTextBlock.tsx",
      "content": "\"use client\";\n\nimport React, { useId } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\n// ==========================================\n// CIRCULAR TEXT\n// Words set on a circle, turning slowly, with room in the middle for a mark\n// or a button. The ring is an SVG textPath so it stays crisp at any size and\n// the text is real text — screen readers get it once, from the sr-only copy.\n// ==========================================\n\nexport interface CircularTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> {\n  /** The words on the ring. */\n  text: string;\n  /** Separator placed between repeats of `text`. */\n  separator?: string;\n  /** How many times `text` goes round. Leave unset to fill the ring by length. */\n  repeat?: number;\n  /** Outer size in pixels. */\n  size?: number;\n  /** Seconds per full turn; `0` holds still. */\n  speed?: number;\n  direction?: \"clockwise\" | \"counterclockwise\";\n  /** Font size of the ring text, in SVG units of a 100-wide circle (≈ percent of size). */\n  fontSize?: number;\n  /** Letter spacing of the ring text, in em. */\n  tracking?: number;\n  /** Colour of the ring text; the theme's primary by default. */\n  color?: string;\n  /** Radius of the text path, out of 50. */\n  radius?: number;\n  /** A thin inner ring, for badges that want an edge. */\n  innerRing?: boolean;\n  /** What sits in the middle. */\n  children?: React.ReactNode;\n}\n\nexport const CircularText = React.forwardRef<HTMLDivElement, CircularTextProps>(\n  (\n    {\n      text,\n      separator = \" · \",\n      repeat,\n      size = 128,\n      speed = 22,\n      direction = \"clockwise\",\n      fontSize = 9.5,\n      tracking = 0.18,\n      color = \"var(--primary)\",\n      radius = 38,\n      innerRing = false,\n      className,\n      style,\n      children,\n      ...props\n    },\n    ref,\n  ) => {\n    const id = useId();\n    // Enough repeats to fill the circumference, unless told otherwise. A\n    // character at this size is about 0.62em wide; the separator counts too.\n    const unit = `${text}${separator}`;\n    const circumference = 2 * Math.PI * radius;\n    const perChar = fontSize * (0.62 + tracking);\n    const count = repeat ?? Math.max(1, Math.floor(circumference / (unit.length * perChar)));\n    const ring = unit.repeat(count);\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\"relative grid place-items-center\", className)}\n        style={{ width: size, height: size, ...style }}\n        {...props}\n      >\n        <svg\n          viewBox=\"0 0 100 100\"\n          className={cn(\n            \"absolute inset-0 size-full motion-reduce:animate-none\",\n            speed > 0 && \"animate-[spin_var(--ct-speed)_linear_infinite]\",\n            direction === \"counterclockwise\" && \"[animation-direction:reverse]\",\n          )}\n          style={{ \"--ct-speed\": `${speed}s` } as React.CSSProperties}\n          aria-hidden\n        >\n          <defs>\n            <path\n              id={id}\n              d={`M 50,50 m -${radius},0 a ${radius},${radius} 0 1,1 ${radius * 2},0 a ${radius},${radius} 0 1,1 -${radius * 2},0`}\n            />\n          </defs>\n          <text\n            className=\"font-sans font-semibold\"\n            style={{ fill: color, fontSize, letterSpacing: `${tracking}em` }}\n          >\n            <textPath href={`#${id}`} startOffset=\"0\">\n              {ring}\n            </textPath>\n          </text>\n        </svg>\n        {innerRing && (\n          <span\n            className=\"absolute rounded-full border border-foreground/15\"\n            style={{ inset: `${49 - radius}%` }}\n            aria-hidden\n          />\n        )}\n        {children && <span className=\"relative grid place-items-center\">{children}</span>}\n        <span className=\"sr-only\">{text}</span>\n      </div>\n    );\n  },\n);\nCircularText.displayName = \"CircularText\";\n\nexport default CircularText;\n",
      "type": "registry:component",
      "target": "components/custom/blocks/CircularTextBlock.tsx"
    }
  ],
  "docs": "Named export: CircularText. `text` repeats to fill the ring (or `repeat` times), `size` in px, `speed` seconds per turn (0 holds still), `direction`, `fontSize`/`tracking` in units of a 100-wide circle, `color` (currentColor follows the parent), `innerRing`. Children sit in the middle. Holds still under prefers-reduced-motion.",
  "categories": [
    "typography"
  ],
  "type": "registry:component"
}
