{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "shadow-sweep-text",
  "title": "Shadow Sweep Text",
  "description": "A line rises up and left while one dense dark shadow uncovers it and a second shadow sweeps back across it for the exit.",
  "dependencies": ["remotion"],
  "files": [
    {
      "path": "registry/remocn/shadow-sweep-text/index.tsx",
      "content": "\"use client\";\n\nimport { Easing, interpolate, useCurrentFrame } from \"remotion\";\n\nexport interface ShadowSweepTextProps {\n  text: string;\n  fontSize?: number;\n  color?: string;\n  fontWeight?: number;\n  backgroundColor?: string;\n  shadowColor?: string;\n  shadowSoftness?: number;\n  rise?: number;\n  driftLeft?: number;\n  speed?: number;\n  className?: string;\n}\n\nexport const shadowSweepTextLength = 37;\n\nconst ENTER_END = 23;\nconst EXIT_START = 26;\nconst EXIT_END = shadowSweepTextLength - 1;\nconst REST_X = -20;\nconst REST_Y = 9;\nconst clamp = {\n  extrapolateLeft: \"clamp\" as const,\n  extrapolateRight: \"clamp\" as const,\n};\n\nexport function ShadowSweepText({\n  text,\n  fontSize = 96,\n  color = \"#aaa6b5\",\n  fontWeight = 700,\n  backgroundColor = \"#030012\",\n  shadowColor = backgroundColor,\n  shadowSoftness = 130,\n  rise = 96,\n  driftLeft = 16,\n  speed = 1,\n  className,\n}: ShadowSweepTextProps) {\n  const frame = useCurrentFrame() * speed;\n  const safeSoftness = Math.max(shadowSoftness, 0);\n  const travelProgress = interpolate(\n    frame,\n    [0, shadowSweepTextLength - 1],\n    [0, 1],\n    {\n      ...clamp,\n      easing: Easing.out(Easing.cubic),\n    },\n  );\n  const enterProgress = interpolate(frame, [-3, ENTER_END], [0, 1], clamp);\n  const exitProgress = interpolate(\n    frame,\n    [EXIT_START, EXIT_END],\n    [0, 1],\n    clamp,\n  );\n  const x = REST_X + driftLeft * (1 - travelProgress);\n  const y = REST_Y + rise * (1 - travelProgress);\n  const isEntering = frame < ENTER_END;\n  const isExiting = frame >= EXIT_START;\n  const sweepProgress = isEntering\n    ? enterProgress\n    : isExiting\n      ? exitProgress\n      : null;\n  const edgeOffset =\n    sweepProgress === null ? 0 : (sweepProgress * 2 - 1) * (safeSoftness / 2);\n  const edgePosition =\n    sweepProgress === null\n      ? \"50%\"\n      : `calc(${sweepProgress * 100}% + ${edgeOffset}px)`;\n  const maskStart =\n    sweepProgress === null\n      ? \"50%\"\n      : `calc(${sweepProgress * 100}% + ${edgeOffset - safeSoftness / 2}px)`;\n  const maskEnd =\n    sweepProgress === null\n      ? \"50%\"\n      : `calc(${sweepProgress * 100}% + ${edgeOffset + safeSoftness / 2}px)`;\n  const textMask = isEntering\n    ? `linear-gradient(90deg, #000 0, #000 ${maskStart}, transparent ${maskEnd}, transparent 100%)`\n    : isExiting\n      ? `linear-gradient(90deg, transparent 0, transparent ${maskStart}, #000 ${maskEnd}, #000 100%)`\n      : undefined;\n  const fieldOpacity =\n    sweepProgress === null\n      ? 0\n      : interpolate(sweepProgress, [0, 0.08, 0.82, 1], [0, 1, 1, 0], clamp);\n  const fieldWidth = Math.max(safeSoftness * 3, 1);\n  const fieldHeight = Math.max(fontSize * 2.6, safeSoftness * 1.8, 1);\n\n  if (text.length === 0) {\n    return (\n      <div\n        className={className}\n        style={{ position: \"absolute\", inset: 0, backgroundColor }}\n      />\n    );\n  }\n\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        overflow: \"hidden\",\n        backgroundColor,\n      }}\n    >\n      <div\n        style={{\n          position: \"relative\",\n          display: \"inline-block\",\n          transform: `translate3d(${x}px, ${y}px, 0)`,\n        }}\n      >\n        <span\n          style={{\n            color,\n            display: \"inline-block\",\n            fontFamily: \"Arial, Helvetica, sans-serif\",\n            fontSize,\n            fontWeight,\n            letterSpacing: 0,\n            lineHeight: 1,\n            maskImage: textMask,\n            maskRepeat: \"no-repeat\",\n            opacity: 1,\n            WebkitMaskImage: textMask,\n            WebkitMaskRepeat: \"no-repeat\",\n            whiteSpace: \"nowrap\",\n          }}\n        >\n          {text}\n        </span>\n\n        <div\n          style={{\n            position: \"absolute\",\n            top: \"50%\",\n            left: edgePosition,\n            width: fieldWidth,\n            height: fieldHeight,\n            background: `radial-gradient(ellipse at center, ${shadowColor} 0%, ${shadowColor} 14%, transparent 72%)`,\n            filter: `blur(${safeSoftness * 0.08}px)`,\n            opacity: fieldOpacity,\n            pointerEvents: \"none\",\n            transform: \"translate3d(-50%, -50%, 0)\",\n          }}\n        />\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/shadow-sweep-text.tsx"
    }
  ],
  "type": "registry:component"
}
