{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "caption-glitch-rgb",
  "title": "Caption Glitch RGB",
  "description": "Captions with a glitchy RGB-split effect on each word.",
  "dependencies": [
    "@editframe/react"
  ],
  "files": [
    {
      "path": "registry/bases/editframe/components/caption-glitch-rgb/index.tsx",
      "content": "\"use client\";\n\nimport { Timegroup } from \"@editframe/react\";\nimport type { CSSProperties } from \"react\";\n\nexport interface CaptionWord {\n  text: string;\n  start: number;\n  end: number;\n}\n\nexport interface CaptionGlitchRgbProps {\n  words?: CaptionWord[];\n  color?: string;\n  glitchRedColor?: string;\n  glitchCyanColor?: string;\n  fontSize?: number;\n  fontWeight?: number | string;\n  background?: string;\n  speed?: number;\n  fps?: number;\n  durationInFrames?: number;\n  width?: number;\n  height?: number;\n  className?: string;\n}\n\nconst DEFAULT_WORDS: CaptionWord[] = [\n  { end: 0.35, start: 0, text: \"Every\" },\n  { end: 0.65, start: 0.35, text: \"great\" },\n  { end: 1, start: 0.65, text: \"video\" },\n  { end: 1.45, start: 1.1, text: \"starts\" },\n  { end: 1.65, start: 1.45, text: \"with\" },\n  { end: 1.8, start: 1.65, text: \"a\" },\n  { end: 2.15, start: 1.8, text: \"single\" },\n  { end: 2.7, start: 2.15, text: \"frame.\" },\n  { end: 3.2, start: 3, text: \"No\" },\n  { end: 3.9, start: 3.2, text: \"timelines.\" },\n  { end: 4.2, start: 4, text: \"No\" },\n  { end: 4.5, start: 4.2, text: \"drag\" },\n  { end: 4.65, start: 4.5, text: \"and\" },\n  { end: 5.1, start: 4.65, text: \"drop.\" },\n  { end: 5.55, start: 5.3, text: \"Just\" },\n  { end: 6, start: 5.55, text: \"code.\" },\n];\n\nconst WORDS_PER_GROUP = 3;\n\nexport const CaptionGlitchRgb = ({\n  words = DEFAULT_WORDS,\n  color = \"#ffffff\",\n  glitchRedColor = \"#ff003c\",\n  glitchCyanColor = \"#00e5ff\",\n  fontSize = 88,\n  fontWeight = 700,\n  background = \"#0a0a0a\",\n  speed = 1,\n  fps = 30,\n  durationInFrames = 180,\n  width = 1280,\n  height = 720,\n  className,\n}: CaptionGlitchRgbProps) => {\n  const safeSpeed = Math.max(0.01, speed);\n  const durationMs = (durationInFrames / fps) * 1000;\n\n  const groups = [];\n  for (let i = 0; i < words.length; i += WORDS_PER_GROUP) {\n    const groupWords = words.slice(i, i + WORDS_PER_GROUP);\n    groups.push({\n      endMs: ((groupWords.at(-1)?.end ?? 0) * 1000) / safeSpeed + 180,\n      startMs: (groupWords[0].start * 1000) / safeSpeed,\n      words: groupWords,\n    });\n  }\n\n  const containerStyle: CSSProperties = {\n    background,\n    height,\n    overflow: \"hidden\",\n    position: \"relative\",\n    width,\n  };\n\n  return (\n    <Timegroup\n      className={className}\n      duration={`${durationMs}ms`}\n      mode=\"fixed\"\n      style={containerStyle}\n    >\n      <>\n        <style>{`\n          @keyframes framecn-cgr-grp-in {\n            from { opacity: 0; }\n            to   { opacity: 1; }\n          }\n          @keyframes framecn-cgr-grp-out {\n            from { opacity: 1; }\n            to   { opacity: 0; }\n          }\n          @keyframes framecn-cgr-glitch-6 {\n            from { transform: translateX(-6px); text-shadow: 5px 0 ${glitchRedColor}, -5px 0 ${glitchCyanColor}, 0 5px 18px rgba(0,0,0,0.52); }\n            to   { transform: translateX(0); text-shadow: 0 5px 18px rgba(0,0,0,0.52); }\n          }\n          @keyframes framecn-cgr-glitch-8 {\n            from { transform: translateX(-8px); text-shadow: 5px 0 ${glitchRedColor}, -5px 0 ${glitchCyanColor}, 0 5px 18px rgba(0,0,0,0.52); }\n            to   { transform: translateX(0); text-shadow: 0 5px 18px rgba(0,0,0,0.52); }\n          }\n          @keyframes framecn-cgr-glitch-12 {\n            from { transform: translateX(-12px); text-shadow: 5px 0 ${glitchRedColor}, -5px 0 ${glitchCyanColor}, 0 5px 18px rgba(0,0,0,0.52); }\n            to   { transform: translateX(0); text-shadow: 0 5px 18px rgba(0,0,0,0.52); }\n          }\n        `}</style>\n        {/* Scanlines overlay */}\n        <div\n          aria-hidden\n          style={{\n            backgroundImage:\n              \"repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.08) 2px, rgba(0,0,0,0.08) 4px)\",\n            inset: 0,\n            pointerEvents: \"none\",\n            position: \"absolute\",\n            zIndex: 10,\n          }}\n        />\n        <div\n          style={{\n            bottom: Math.round(height * 0.15),\n            left: 0,\n            position: \"absolute\",\n            right: 0,\n          }}\n        >\n          {groups.map((group, gi) => (\n            <div\n              key={gi}\n              style={{\n                alignItems: \"center\",\n                animation: [\n                  `framecn-cgr-grp-in 80ms ease-out ${group.startMs}ms both`,\n                  `framecn-cgr-grp-out 80ms ease-in ${group.endMs}ms forwards`,\n                ].join(\", \"),\n                display: \"flex\",\n                flexWrap: \"wrap\",\n                gap: \"0.3em\",\n                justifyContent: \"center\",\n                left: 0,\n                opacity: 0,\n                padding: \"0 80px\",\n                position: \"absolute\",\n                right: 0,\n              }}\n            >\n              {group.words.map((word, wi) => {\n                const wordStartMs = (word.start * 1000) / safeSpeed;\n                const travelVariants = [\n                  \"framecn-cgr-glitch-8\",\n                  \"framecn-cgr-glitch-12\",\n                  \"framecn-cgr-glitch-6\",\n                ];\n                const keyframeName = travelVariants[wi % 3];\n\n                return (\n                  <span\n                    key={wi}\n                    style={{\n                      animation: `${keyframeName} 200ms cubic-bezier(0.16,1,0.3,1) ${wordStartMs}ms both`,\n                      color,\n                      display: \"inline-block\",\n                      fontFamily:\n                        \"'Space Grotesk', var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\",\n                      fontSize,\n                      fontWeight,\n                      letterSpacing: \"0.02em\",\n                      lineHeight: 1,\n                      textShadow: `0 5px 18px rgba(0,0,0,0.52)`,\n                    }}\n                  >\n                    {word.text}\n                  </span>\n                );\n              })}\n            </div>\n          ))}\n        </div>\n      </>\n    </Timegroup>\n  );\n};\n",
      "type": "registry:component",
      "target": "components/framecn/caption-glitch-rgb.tsx"
    }
  ],
  "type": "registry:component"
}