{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "line-by-line-slide",
  "title": "Line-by-Line Slide",
  "description": "Each line enters from the left with a staggered slide and exits to the right for a flowing paragraph reveal.",
  "dependencies": ["remotion"],
  "files": [
    {
      "path": "registry/remocn/line-by-line-slide/index.tsx",
      "content": "\"use client\";\n\nimport { Easing, interpolate, useCurrentFrame, useVideoConfig } from \"remotion\";\n\nexport interface LineByLineSlideProps {\n  text: string;\n  distance?: number;\n  fontSize?: number;\n  color?: string;\n  fontWeight?: number;\n  speed?: number;\n  className?: string;\n}\n\nexport function LineByLineSlide({\n  text,\n  distance = 48,\n  fontSize = 72,\n  color = \"#171717\",\n  fontWeight = 600,\n  speed = 1,\n  className,\n}: LineByLineSlideProps) {\n  const frame = useCurrentFrame() * speed;\n  const { durationInFrames } = useVideoConfig();\n\n  const lines = text.split(\"\\n\");\n\n  const enterDur = 27;\n  const enterTravel = 14;\n  const exitDur = 18;\n  const exitTravelFrom = 8;\n  const enterStagger = 4;\n  const exitStagger = 2;\n\n  const enterEasing = Easing.bezier(0.22, 1, 0.36, 1);\n  const exitEasing = Easing.bezier(0.64, 0, 0.78, 0);\n\n  const enterEnd = enterDur + (lines.length - 1) * enterStagger;\n  const exitStart = Math.max(\n    enterEnd,\n    durationInFrames - exitDur - (lines.length - 1) * exitStagger,\n  );\n\n  return (\n    <div\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        background: \"transparent\",\n      }}\n    >\n      <span\n        className={className}\n        style={{\n          fontSize,\n          fontWeight,\n          color,\n          letterSpacing: \"-0.03em\",\n          lineHeight: 1.1,\n          textAlign: \"left\",\n          fontFamily:\n            \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\",\n        }}\n      >\n        {lines.map((line, i) => {\n          const enterLocal = frame - i * enterStagger;\n          const exitLocal = frame - exitStart - i * exitStagger;\n\n          const enterP = interpolate(enterLocal, [0, enterDur], [0, 1], {\n            extrapolateLeft: \"clamp\",\n            extrapolateRight: \"clamp\",\n            easing: enterEasing,\n          });\n\n          const exitP = interpolate(exitLocal, [0, exitDur], [0, 1], {\n            extrapolateLeft: \"clamp\",\n            extrapolateRight: \"clamp\",\n            easing: exitEasing,\n          });\n\n          const opacity = enterP * (1 - exitP);\n\n          const xEnter = interpolate(\n            enterLocal,\n            [0, enterTravel],\n            [-distance, 0],\n            {\n              extrapolateLeft: \"clamp\",\n              extrapolateRight: \"clamp\",\n              easing: enterEasing,\n            },\n          );\n\n          const xExit = interpolate(\n            exitLocal,\n            [exitTravelFrom, exitDur],\n            [0, distance],\n            {\n              extrapolateLeft: \"clamp\",\n              extrapolateRight: \"clamp\",\n              easing: exitEasing,\n            },\n          );\n\n          const x = xEnter + xExit;\n\n          return (\n            <span\n              key={i}\n              style={{\n                display: \"block\",\n                transformOrigin: \"0% 50%\",\n                opacity,\n                translate: `${x}px`,\n              }}\n            >\n              {line}\n            </span>\n          );\n        })}\n      </span>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/line-by-line-slide.tsx"
    }
  ],
  "type": "registry:component"
}
