{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "fog-rise",
  "title": "Fog Rise",
  "description": "Display text resolves out of fog: characters sharpen from heavy blur center-out with vertical streaks dissolving above them, as if rising along the z-axis.",
  "dependencies": ["remotion"],
  "files": [
    {
      "path": "registry/remocn/fog-rise/index.tsx",
      "content": "\"use client\";\n\nimport { interpolate, spring, useCurrentFrame, useVideoConfig } from \"remotion\";\n\nexport interface FogRiseProps {\n  text: string;\n  fontSize?: number;\n  color?: string;\n  fontWeight?: number;\n  stagger?: number;\n  blur?: number;\n  tilt?: number;\n  depth?: number;\n  lift?: number;\n  drift?: number;\n  exitAt?: number;\n  exitAccel?: number;\n  mass?: number;\n  stiffness?: number;\n  damping?: number;\n  spreadGap?: number;\n  tracking?: number;\n  resolveFrames?: number;\n  fadeFrames?: number;\n  speed?: number;\n  className?: string;\n}\n\nexport function fogRiseLength(\n  text: string,\n  stagger = 5,\n  resolveFrames = 22,\n): number {\n  const chars = Array.from(text);\n  if (chars.length === 0) return 0;\n  const center = (chars.length - 1) / 2;\n  const maxRing = Math.floor(center);\n  return maxRing * stagger + resolveFrames;\n}\n\nexport function FogRise({\n  text,\n  fontSize = 304,\n  color = \"#004CFF\",\n  fontWeight = 400,\n  stagger = 5,\n  blur = 0.17,\n  tilt = 55,\n  depth = 5,\n  lift = 0.85,\n  drift = 0.005,\n  exitAt = 60,\n  exitAccel = 0.04,\n  mass = 1.3,\n  stiffness = 60,\n  damping = 13,\n  spreadGap = 0.07,\n  tracking = -0.07,\n  resolveFrames = 22,\n  fadeFrames = 18,\n  speed = 1,\n  className,\n}: FogRiseProps) {\n  const frame = useCurrentFrame() * speed;\n  const { fps } = useVideoConfig();\n\n  const chars = Array.from(text);\n  const center = (chars.length - 1) / 2;\n  const minRing = chars.length % 2 === 0 ? 0.5 : 0;\n  const maxRing = Math.floor(center);\n\n  const converge = spring({\n    frame,\n    fps,\n    config: { mass, stiffness, damping },\n  });\n  const angle = tilt * (1 - converge);\n  const liftY = lift * fontSize * (1 - converge);\n  const driftY = drift * fontSize * frame;\n  const exitT = exitAt > 0 ? Math.max(frame - exitAt, 0) : 0;\n  const exitY = 0.5 * exitAccel * exitT * exitT * fontSize;\n  const gap = spreadGap * fontSize * (1 - converge);\n\n  return (\n    <div\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        display: \"flex\",\n        alignItems: \"flex-end\",\n        justifyContent: \"center\",\n        paddingBottom: \"6%\",\n        whiteSpace: \"nowrap\",\n        perspective: `${depth * fontSize}px`,\n        background: \"transparent\",\n      }}\n    >\n      <span\n        className={className}\n        style={{\n          transform: `translateY(${liftY - driftY - exitY}px) rotateX(${-angle}deg)`,\n          transformOrigin: \"50% 100%\",\n          fontSize,\n          fontWeight,\n          color,\n          letterSpacing: `${tracking}em`,\n          lineHeight: 1.15,\n          fontFamily:\n            \"var(--font-geist-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif)\",\n        }}\n      >\n        {chars.map((char, j) => {\n          const ring = Math.abs(j - center) - minRing;\n          const startAt = ring * stagger;\n\n          const opacity = interpolate(\n            frame,\n            [startAt, startAt + fadeFrames],\n            [0, 1],\n            { extrapolateLeft: \"clamp\", extrapolateRight: \"clamp\" },\n          );\n\n          const charBlur =\n            blur *\n            fontSize *\n            interpolate(frame, [0, maxRing * stagger + resolveFrames], [1, 0], {\n              extrapolateLeft: \"clamp\",\n              extrapolateRight: \"clamp\",\n            });\n\n          return (\n            <span\n              key={j}\n              style={{\n                display: \"inline-block\",\n                whiteSpace: \"pre\",\n                marginRight: j < chars.length - 1 ? gap : undefined,\n                opacity,\n                filter: charBlur > 0.05 ? `blur(${charBlur}px)` : undefined,\n              }}\n            >\n              {char}\n            </span>\n          );\n        })}\n      </span>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/fog-rise.tsx"
    }
  ],
  "type": "registry:component"
}
