{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "highlighted-text",
  "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",
      "content": "\"use client\"\n\nimport { cn } from \"cn\"\nimport type * as React from \"react\"\nimport { useId } from \"react\"\n\nconst STAR_SPRITE = \"url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 35 7' shape-rendering='crispEdges'%3E%3Crect x='10' y='3' width='1' height='1'/%3E%3Crect x='17' y='1' width='1' height='1'/%3E%3Crect x='17' y='2' width='1' height='1'/%3E%3Crect x='15' y='3' width='1' height='1'/%3E%3Crect x='16' y='3' width='1' height='1'/%3E%3Crect x='17' y='3' width='1' height='1'/%3E%3Crect x='18' y='3' width='1' height='1'/%3E%3Crect x='19' y='3' width='1' height='1'/%3E%3Crect x='17' y='4' width='1' height='1'/%3E%3Crect x='17' y='5' width='1' height='1'/%3E%3Crect x='24' y='1' width='1' height='1'/%3E%3Crect x='23' y='2' width='1' height='1'/%3E%3Crect x='24' y='2' width='1' height='1'/%3E%3Crect x='25' y='2' width='1' height='1'/%3E%3Crect x='22' y='3' width='1' height='1'/%3E%3Crect x='23' y='3' width='1' height='1'/%3E%3Crect x='24' y='3' width='1' height='1'/%3E%3Crect x='25' y='3' width='1' height='1'/%3E%3Crect x='26' y='3' width='1' height='1'/%3E%3Crect x='23' y='4' width='1' height='1'/%3E%3Crect x='24' y='4' width='1' height='1'/%3E%3Crect x='25' y='4' width='1' height='1'/%3E%3Crect x='24' y='5' width='1' height='1'/%3E%3Crect x='31' y='0' width='1' height='1'/%3E%3Crect x='31' y='1' width='1' height='1'/%3E%3Crect x='30' y='2' width='1' height='1'/%3E%3Crect x='31' y='2' width='1' height='1'/%3E%3Crect x='32' y='2' width='1' height='1'/%3E%3Crect x='28' y='3' width='1' height='1'/%3E%3Crect x='29' y='3' width='1' height='1'/%3E%3Crect x='30' y='3' width='1' height='1'/%3E%3Crect x='31' y='3' width='1' height='1'/%3E%3Crect x='32' y='3' width='1' height='1'/%3E%3Crect x='33' y='3' width='1' height='1'/%3E%3Crect x='34' y='3' width='1' height='1'/%3E%3Crect x='30' y='4' width='1' height='1'/%3E%3Crect x='31' y='4' width='1' height='1'/%3E%3Crect x='32' y='4' width='1' height='1'/%3E%3Crect x='31' y='5' width='1' height='1'/%3E%3Crect x='31' y='6' width='1' height='1'/%3E%3C/svg%3E\\\")\"\n\nconst PIXEL = \"var(--pixel, 2px)\"\nconst STAR_CELLS = 7\nconst FRAME_SEQUENCE = [\n  { at: \"0%, 70%\", frame: 0 },\n  { at: \"73%\", frame: 1 },\n  { at: \"76%\", frame: 2 },\n  { at: \"79%\", frame: 3 },\n  { at: \"82%\", frame: 4 },\n  { at: \"86%\", frame: 3 },\n  { at: \"89%\", frame: 2 },\n  { at: \"92%\", frame: 1 },\n  { at: \"95%, 100%\", frame: 0 },\n] as const\nconst FRAME_COUNT = 5\nconst STILL_FRAME = 2\n\nconst MAX_NUDGE = 3\nconst PERIOD_JITTER = 0.6\n\ntype Corner = \"top-left\" | \"top-right\" | \"bottom-right\" | \"bottom-left\"\n\ntype StarAnchor = {\n  position: string\n  towardX: -1 | 1\n  towardY: -1 | 1\n  period: number\n}\n\nconst STARS: Record<Corner, StarAnchor> = {\n  \"top-left\": { position: \"top-0 left-0\", towardX: -1, towardY: -1, period: 3.7 },\n  \"top-right\": { position: \"top-0 right-0\", towardX: 1, towardY: -1, period: 4.3 },\n  \"bottom-right\": { position: \"right-0 bottom-0\", towardX: 1, towardY: 1, period: 3.1 },\n  \"bottom-left\": { position: \"bottom-0 left-0\", towardX: -1, towardY: 1, period: 4.9 },\n}\n\nfunction createRandom(seed: string): () => number {\n  let state = [...seed].reduce((hash, char) => Math.imul(hash ^ char.charCodeAt(0), 16777619), 2166136261)\n  return () => {\n    state = (state + 0x6d2b79f5) | 0\n    let mixed = Math.imul(state ^ (state >>> 15), 1 | state)\n    mixed = (mixed + Math.imul(mixed ^ (mixed >>> 7), 61 | mixed)) ^ mixed\n    return ((mixed ^ (mixed >>> 14)) >>> 0) / 4294967296\n  }\n}\n\nfunction readNudge(random: () => number): number {\n  return Math.floor(random() * (MAX_NUDGE * 2 + 1)) - MAX_NUDGE\n}\n\nfunction readStarStyle(anchor: StarAnchor, random: () => number): StarStyle {\n  const nudgeX = readNudge(random)\n  const period = anchor.period + (random() * 2 - 1) * PERIOD_JITTER\n  return {\n    translate: `calc(${anchor.towardX * 50}% + ${PIXEL} * ${nudgeX}) ${anchor.towardY * 50}%`,\n    \"--twinkle-period\": `${period.toFixed(2)}s`,\n    \"--twinkle-delay\": `${(-random() * period).toFixed(2)}s`,\n  }\n}\n\nfunction readFrameOffset(frame: number): string {\n  return `calc(${PIXEL} * ${-frame * STAR_CELLS}) 0`\n}\n\nconst STYLES = `\n@keyframes ui95-twinkle {\n${FRAME_SEQUENCE.map(({ at, frame }) => `  ${at} { mask-position: ${readFrameOffset(frame)}; }`).join(\"\\n\")}\n}\n[data-slot=\"highlighted-text-star\"] {\n  width: calc(${PIXEL} * ${STAR_CELLS});\n  height: calc(${PIXEL} * ${STAR_CELLS});\n  background-color: currentColor;\n  mask-image: ${STAR_SPRITE};\n  mask-size: calc(${PIXEL} * ${STAR_CELLS * FRAME_COUNT}) calc(${PIXEL} * ${STAR_CELLS});\n  mask-repeat: no-repeat;\n  mask-position: 0 0;\n  animation: ui95-twinkle var(--twinkle-period) steps(1, end) var(--twinkle-delay) infinite;\n}\n@media (prefers-reduced-motion: reduce) {\n  [data-slot=\"highlighted-text-star\"] {\n    animation: none;\n    mask-position: ${readFrameOffset(STILL_FRAME)};\n  }\n}\n`\n\ntype StarStyle = React.CSSProperties & {\n  \"--twinkle-period\": string\n  \"--twinkle-delay\": string\n}\n\nfunction HighlightedText({ className, children, ...props }: React.ComponentProps<\"span\">) {\n  const random = createRandom(useId())\n  return (\n    <span data-slot=\"highlighted-text\" className={cn(\"relative inline-block\", className)} {...props}>\n      <style href=\"ui95-highlighted-text\" precedence=\"default\">\n        {STYLES}\n      </style>\n      {children}\n      {Object.entries(STARS).map(([corner, anchor]) => (\n        <span\n          key={corner}\n          aria-hidden=\"true\"\n          data-slot=\"highlighted-text-star\"\n          className={cn(\"pointer-events-none absolute\", anchor.position)}\n          style={readStarStyle(anchor, random)}\n        />\n      ))}\n    </span>\n  )\n}\n\nexport { HighlightedText }\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "ui"
  ],
  "type": "registry:ui"
}