{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ai-generation-canvas",
  "title": "AI Generation Canvas",
  "description": "A prompt input transforms into a header, then a skeleton dashboard flips into populated cards.",
  "dependencies": [
    "remotion"
  ],
  "files": [
    {
      "path": "registry/bases/editframe/components/ai-generation-canvas/index.tsx",
      "content": "\"use client\";\n\nimport { Timegroup } from \"@editframe/react\";\nimport type { CSSProperties } from \"react\";\n\nexport interface AIGenerationCanvasProps {\n  prompt?: string;\n  accentColor?: string;\n  cardCount?: number;\n  speed?: number;\n  fps?: number;\n  durationInFrames?: number;\n  className?: string;\n}\n\nconst FONT_FAMILY =\n  \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\";\n\nconst MiniBarChart = ({ accentColor }: { accentColor: string }) => {\n  const bars = [0.4, 0.7, 0.55, 0.85, 0.5, 0.95, 0.65];\n  return (\n    <div\n      style={{\n        alignItems: \"flex-end\",\n        display: \"flex\",\n        gap: 6,\n        height: 60,\n        marginTop: 12,\n      }}\n    >\n      {bars.map((h, i) => (\n        <div\n          key={i}\n          style={{\n            background: accentColor,\n            borderRadius: 3,\n            flex: 1,\n            height: `${h * 100}%`,\n            opacity: 0.3 + h * 0.7,\n          }}\n        />\n      ))}\n    </div>\n  );\n};\n\nconst MiniRows = () => (\n  <div\n    style={{\n      display: \"flex\",\n      flexDirection: \"column\",\n      gap: 6,\n      marginTop: 12,\n    }}\n  >\n    {[0.9, 0.7, 0.85, 0.6].map((w, i) => (\n      <div\n        key={i}\n        style={{\n          background: \"rgba(255,255,255,0.12)\",\n          borderRadius: 4,\n          height: 8,\n          width: `${w * 100}%`,\n        }}\n      />\n    ))}\n  </div>\n);\n\nconst StatBlock = ({\n  accentColor,\n  value,\n}: {\n  accentColor: string;\n  value: string;\n}) => (\n  <div style={{ marginTop: 8 }}>\n    <div\n      style={{\n        color: \"white\",\n        fontFamily: FONT_FAMILY,\n        fontSize: 36,\n        fontWeight: 700,\n        letterSpacing: \"-0.03em\",\n      }}\n    >\n      {value}\n    </div>\n    <div\n      style={{\n        color: accentColor,\n        fontSize: 12,\n        fontWeight: 500,\n        marginTop: 2,\n      }}\n    >\n      +12.4% this week\n    </div>\n  </div>\n);\n\nconst CardContent = ({\n  index,\n  accentColor,\n}: {\n  index: number;\n  accentColor: string;\n}) => {\n  const titles = [\n    \"Revenue\",\n    \"Active Users\",\n    \"Sessions\",\n    \"Conversion\",\n    \"Retention\",\n    \"Latency\",\n  ];\n  const values = [\"$48.2k\", \"12,840\", \"9.1k\", \"3.8%\", \"76%\", \"142ms\"];\n  const variant = index % 3;\n\n  let content;\n  if (variant === 0) {\n    content = (\n      <>\n        <StatBlock\n          accentColor={accentColor}\n          value={values[index % values.length]}\n        />\n        <MiniBarChart accentColor={accentColor} />\n      </>\n    );\n  } else if (variant === 1) {\n    content = (\n      <>\n        <StatBlock\n          accentColor={accentColor}\n          value={values[index % values.length]}\n        />\n        <MiniRows />\n      </>\n    );\n  } else {\n    content = (\n      <>\n        <MiniBarChart accentColor={accentColor} />\n        <MiniRows />\n      </>\n    );\n  }\n\n  return (\n    <div style={{ height: \"100%\", padding: 18, width: \"100%\" }}>\n      <div\n        style={{\n          color: \"rgba(255,255,255,0.55)\",\n          fontFamily: FONT_FAMILY,\n          fontSize: 12,\n          fontWeight: 500,\n          letterSpacing: \"0.02em\",\n          textTransform: \"uppercase\",\n        }}\n      >\n        {titles[index % titles.length]}\n      </div>\n      {content}\n    </div>\n  );\n};\n\nexport const AIGenerationCanvas = ({\n  prompt = \"Generate a dashboard\",\n  accentColor = \"#7c3aed\",\n  cardCount = 4,\n  speed = 1,\n  fps = 30,\n  durationInFrames = 180,\n  className,\n}: AIGenerationCanvasProps) => {\n  const safeSpeed = Math.max(0.01, speed);\n  const durationMs = ((durationInFrames / fps) * 1000) / safeSpeed;\n\n  // Phase boundaries (as percentages)\n  const P1_END = (40 / durationInFrames) * 100;\n  const P2_END = (70 / durationInFrames) * 100;\n  const P3_END = (100 / durationInFrames) * 100;\n  const phase4Start = (100 / durationInFrames) * 100;\n\n  const style = {\n    background: \"#0a0a0a\",\n    fontFamily: FONT_FAMILY,\n    height: \"100%\",\n    overflow: \"hidden\",\n    position: \"relative\",\n    width: \"100%\",\n  } as CSSProperties;\n\n  return (\n    <Timegroup\n      className={className}\n      duration={`${durationMs}ms`}\n      mode=\"fixed\"\n      style={style}\n    >\n      <>\n        <style>{`\n          @keyframes framecn-ai-canvas-typewriter {\n            from {\n              max-width: 0;\n            }\n            ${P1_END}% {\n              max-width: 640px;\n            }\n            ${P2_END}% {\n              max-width: 1200px;\n            }\n            100% {\n              max-width: 1200px;\n            }\n          }\n\n          @keyframes framecn-ai-canvas-input-transform {\n            from {\n              top: 320px;\n              width: 640px;\n              height: 80px;\n              margin-left: -320px;\n              border-radius: 16px;\n              font-size: 24px;\n              box-shadow: 0 0 0 6px ${accentColor}11, 0 30px 80px rgba(0,0,0,0.6);\n            }\n            ${P2_END}% {\n              top: 40px;\n              width: 1200px;\n              height: 56px;\n              margin-left: -600px;\n              border-radius: 12px;\n              font-size: 14px;\n              box-shadow: 0 8px 24px rgba(0,0,0,0.4);\n            }\n            100% {\n              top: 40px;\n              width: 1200px;\n              height: 56px;\n              margin-left: -600px;\n              border-radius: 12px;\n              font-size: 14px;\n              box-shadow: 0 8px 24px rgba(0,0,0,0.4);\n            }\n          }\n\n          @keyframes framecn-ai-canvas-skeleton-fade {\n            from {\n              opacity: 0;\n            }\n            ${P2_END}% {\n              opacity: 0;\n            }\n            ${P3_END}% {\n              opacity: 1;\n            }\n            100% {\n              opacity: 1;\n            }\n          }\n\n          @keyframes framecn-ai-canvas-card-flip {\n            from {\n              transform: rotateY(0deg);\n            }\n            50% {\n              transform: rotateY(90deg);\n            }\n            100% {\n              transform: rotateY(180deg);\n            }\n          }\n\n          @keyframes framecn-ai-canvas-shimmer {\n            from {\n              background-position: -200% 0;\n            }\n            to {\n              background-position: 200% 0;\n            }\n          }\n\n          @keyframes framecn-ai-canvas-cursor-blink {\n            0%, 100% {\n              opacity: 1;\n            }\n            50% {\n              opacity: 0;\n            }\n          }\n\n          @keyframes framecn-ai-canvas-status-fade {\n            from {\n              opacity: 0;\n            }\n            ${P2_END}% {\n              opacity: 0;\n            }\n            ${P3_END}% {\n              opacity: 1;\n            }\n            100% {\n              opacity: 1;\n            }\n          }\n        `}</style>\n\n        {/* Subtle grid backdrop */}\n        <div\n          style={{\n            backgroundImage:\n              \"linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px)\",\n            backgroundSize: \"40px 40px\",\n            inset: 0,\n            maskImage:\n              \"radial-gradient(ellipse at center, black 40%, transparent 80%)\",\n            position: \"absolute\",\n          }}\n        />\n\n        {/* Prompt input — centered then transforms to header */}\n        <div\n          style={{\n            alignItems: \"center\",\n            animation: `framecn-ai-canvas-input-transform ${durationMs}ms cubic-bezier(0.16, 1, 0.3, 1) forwards`,\n            backdropFilter: \"blur(12px)\",\n            background: \"rgba(20,20,22,0.85)\",\n            border: `1px solid ${accentColor}55`,\n            borderRadius: 16,\n            display: \"flex\",\n            height: 80,\n            left: \"50%\",\n            marginLeft: -320,\n            padding: \"0 20px\",\n            position: \"absolute\",\n            top: 320,\n            width: 640,\n          }}\n        >\n          {/* Sparkle icon */}\n          <div\n            style={{\n              alignItems: \"center\",\n              color: accentColor,\n              display: \"flex\",\n              flexShrink: 0,\n              height: 20,\n              justifyContent: \"center\",\n              marginRight: 12,\n              width: 20,\n            }}\n          >\n            <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"currentColor\">\n              <path d=\"M12 2l2.5 6.5L21 11l-6.5 2.5L12 20l-2.5-6.5L3 11l6.5-2.5L12 2z\" />\n            </svg>\n          </div>\n          <div\n            style={{\n              animation: `framecn-ai-canvas-typewriter ${durationMs * 0.3}ms steps(${prompt.length}) forwards`,\n              color: \"white\",\n              fontSize: 24,\n              fontWeight: 500,\n              letterSpacing: \"-0.01em\",\n              overflow: \"hidden\",\n              whiteSpace: \"nowrap\",\n            }}\n          >\n            {prompt}\n            <span\n              style={{\n                animation: `framecn-ai-canvas-cursor-blink 0.8s ease-in-out infinite`,\n                background: accentColor,\n                display: \"inline-block\",\n                height: 24,\n                marginLeft: 2,\n                verticalAlign: \"middle\",\n                width: 2,\n              }}\n            />\n          </div>\n          <div\n            style={{\n              alignItems: \"center\",\n              animation: `framecn-ai-canvas-status-fade ${durationMs}ms ease-out forwards`,\n              display: \"flex\",\n              gap: 8,\n              marginLeft: \"auto\",\n            }}\n          >\n            <div\n              style={{\n                background: accentColor,\n                borderRadius: 4,\n                boxShadow: `0 0 12px ${accentColor}`,\n                height: 8,\n                width: 8,\n              }}\n            />\n            <div\n              style={{\n                color: \"rgba(255,255,255,0.6)\",\n                fontSize: 12,\n                fontWeight: 500,\n              }}\n            >\n              Generating\n            </div>\n          </div>\n        </div>\n\n        {/* Skeleton + content cards grid (Phase 3 onward) */}\n        <div\n          style={{\n            animation: `framecn-ai-canvas-skeleton-fade ${durationMs}ms ease-out forwards`,\n            bottom: 40,\n            display: \"grid\",\n            gap: 20,\n            gridTemplateColumns: `repeat(${Math.min(cardCount, 4)}, 1fr)`,\n            left: 40,\n            position: \"absolute\",\n            right: 40,\n            top: 130,\n          }}\n        >\n          {Array.from({ length: cardCount }).map((_, i) => (\n            <div\n              key={i}\n              style={{\n                perspective: 1200,\n                position: \"relative\",\n              }}\n            >\n              <div\n                style={{\n                  animation: `framecn-ai-canvas-card-flip ${900 - i * 100}ms cubic-bezier(0.16, 1, 0.3, 1) ${phase4Start}ms backwards`,\n                  height: \"100%\",\n                  position: \"relative\",\n                  transformStyle: \"preserve-3d\",\n                  width: \"100%\",\n                }}\n              >\n                {/* Skeleton face */}\n                <div\n                  style={{\n                    backfaceVisibility: \"hidden\",\n                    background: \"#141416\",\n                    border: \"1px solid rgba(255,255,255,0.06)\",\n                    borderRadius: 14,\n                    inset: 0,\n                    overflow: \"hidden\",\n                    position: \"absolute\",\n                  }}\n                >\n                  {/* Shimmer overlay */}\n                  <div\n                    style={{\n                      animation: \"framecn-ai-canvas-shimmer 2s linear infinite\",\n                      background: `linear-gradient(110deg, transparent 0%, transparent 30%, ${accentColor}22 45%, transparent 60%, transparent 100%)`,\n                      backgroundSize: \"200% 100%\",\n                      inset: 0,\n                      position: \"absolute\",\n                    }}\n                  />\n                  <div style={{ padding: 18 }}>\n                    <div\n                      style={{\n                        background: \"rgba(255,255,255,0.08)\",\n                        borderRadius: 4,\n                        height: 10,\n                        width: \"40%\",\n                      }}\n                    />\n                    <div\n                      style={{\n                        background: \"rgba(255,255,255,0.08)\",\n                        borderRadius: 6,\n                        height: 28,\n                        marginTop: 14,\n                        width: \"70%\",\n                      }}\n                    />\n                    <div\n                      style={{\n                        background: \"rgba(255,255,255,0.05)\",\n                        borderRadius: 6,\n                        height: 60,\n                        marginTop: 16,\n                        width: \"100%\",\n                      }}\n                    />\n                  </div>\n                </div>\n                {/* Content face */}\n                <div\n                  style={{\n                    backfaceVisibility: \"hidden\",\n                    background: \"#141416\",\n                    border: `1px solid ${accentColor}33`,\n                    borderRadius: 14,\n                    boxShadow: `0 0 0 1px ${accentColor}22, 0 20px 40px rgba(0,0,0,0.4)`,\n                    inset: 0,\n                    overflow: \"hidden\",\n                    position: \"absolute\",\n                    transform: \"rotateY(180deg)\",\n                  }}\n                >\n                  <CardContent index={i} accentColor={accentColor} />\n                </div>\n              </div>\n            </div>\n          ))}\n        </div>\n      </>\n    </Timegroup>\n  );\n};\n",
      "type": "registry:component",
      "target": "components/framecn/ai-generation-canvas.tsx"
    }
  ],
  "type": "registry:component"
}