{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hero-device-assemble",
  "title": "Hero Device Assemble",
  "description": "Floating device layers spring together into a laptop or phone mockup, then the screen wakes with a shimmer.",
  "dependencies": [
    "remotion"
  ],
  "files": [
    {
      "path": "registry/bases/editframe/components/hero-device-assemble/index.tsx",
      "content": "\"use client\";\n\nimport { Timegroup } from \"@editframe/react\";\nimport type { CSSProperties } from \"react\";\n\nconst FONT_FAMILY =\n  \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\";\n\nconst MockUI = ({ accentColor }: { accentColor: string }) => (\n  <div\n    style={{\n      background: \"#0b0b0f\",\n      color: \"white\",\n      display: \"flex\",\n      flexDirection: \"column\",\n      fontFamily: FONT_FAMILY,\n      inset: 0,\n      overflow: \"hidden\",\n      position: \"absolute\",\n    }}\n  >\n    {/* Title bar */}\n    <div\n      style={{\n        alignItems: \"center\",\n        background: \"#111118\",\n        borderBottom: \"1px solid rgba(255,255,255,0.06)\",\n        display: \"flex\",\n        gap: 8,\n        height: \"10%\",\n        padding: \"0 16px\",\n      }}\n    >\n      <div\n        style={{\n          background: \"rgba(255,255,255,0.18)\",\n          borderRadius: \"50%\",\n          height: 10,\n          width: 10,\n        }}\n      />\n      <div\n        style={{\n          background: \"rgba(255,255,255,0.18)\",\n          borderRadius: \"50%\",\n          height: 10,\n          width: 10,\n        }}\n      />\n      <div\n        style={{\n          background: \"rgba(255,255,255,0.18)\",\n          borderRadius: \"50%\",\n          height: 10,\n          width: 10,\n        }}\n      />\n    </div>\n    <div style={{ display: \"flex\", flex: 1 }}>\n      {/* Sidebar */}\n      <div\n        style={{\n          background: \"#0e0e14\",\n          borderRight: \"1px solid rgba(255,255,255,0.05)\",\n          display: \"flex\",\n          flexDirection: \"column\",\n          gap: 10,\n          padding: 16,\n          width: \"22%\",\n        }}\n      >\n        <div\n          style={{\n            background: accentColor,\n            borderRadius: 4,\n            height: 12,\n            opacity: 0.85,\n            width: \"70%\",\n          }}\n        />\n        <div\n          style={{\n            background: \"rgba(255,255,255,0.1)\",\n            borderRadius: 4,\n            height: 10,\n            width: \"85%\",\n          }}\n        />\n        <div\n          style={{\n            background: \"rgba(255,255,255,0.08)\",\n            borderRadius: 4,\n            height: 10,\n            width: \"60%\",\n          }}\n        />\n        <div\n          style={{\n            background: \"rgba(255,255,255,0.08)\",\n            borderRadius: 4,\n            height: 10,\n            width: \"75%\",\n          }}\n        />\n      </div>\n      {/* Content */}\n      <div\n        style={{\n          display: \"flex\",\n          flex: 1,\n          flexDirection: \"column\",\n          gap: 16,\n          padding: 24,\n        }}\n      >\n        <div\n          style={{\n            background: \"rgba(255,255,255,0.85)\",\n            borderRadius: 4,\n            height: 18,\n            width: \"40%\",\n          }}\n        />\n        <div\n          style={{\n            background: \"rgba(255,255,255,0.18)\",\n            borderRadius: 4,\n            height: 10,\n            width: \"65%\",\n          }}\n        />\n        <div\n          style={{\n            display: \"grid\",\n            gap: 12,\n            gridTemplateColumns: \"1fr 1fr 1fr\",\n            marginTop: 12,\n          }}\n        >\n          <div\n            style={{\n              background:\n                \"linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02))\",\n              border: \"1px solid rgba(255,255,255,0.06)\",\n              borderRadius: 8,\n              height: 90,\n            }}\n          />\n          <div\n            style={{\n              background: `linear-gradient(180deg, ${accentColor}33, ${accentColor}11)`,\n              border: `1px solid ${accentColor}55`,\n              borderRadius: 8,\n              height: 90,\n            }}\n          />\n          <div\n            style={{\n              background:\n                \"linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02))\",\n              border: \"1px solid rgba(255,255,255,0.06)\",\n              borderRadius: 8,\n              height: 90,\n            }}\n          />\n        </div>\n        <div\n          style={{\n            background:\n              \"linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.01))\",\n            border: \"1px solid rgba(255,255,255,0.06)\",\n            borderRadius: 8,\n            flex: 1,\n          }}\n        />\n      </div>\n    </div>\n  </div>\n);\n\nexport interface HeroDeviceAssembleProps {\n  assembleStart?: number;\n  device?: \"laptop\" | \"phone\";\n  accentColor?: string;\n  speed?: number;\n  fps?: number;\n  durationInFrames?: number;\n  width?: number;\n  height?: number;\n  className?: string;\n}\n\nexport const HeroDeviceAssemble = ({\n  assembleStart = 0,\n  device = \"laptop\",\n  accentColor = \"#22c55e\",\n  speed = 1,\n  fps = 30,\n  durationInFrames = 150,\n  width = 1280,\n  height = 720,\n  className,\n}: HeroDeviceAssembleProps) => {\n  const safeSpeed = Math.max(0.01, speed);\n  const durationMs = (durationInFrames / fps) * 1000;\n  const frameMs = 1000 / fps;\n  const assembleDelayMs = assembleStart * frameMs;\n  const assembleMs = ((60 / fps) * 1000) / safeSpeed;\n  const settleMs = ((45 / fps) * 1000) / safeSpeed;\n  const shimmerMs = ((30 / fps) * 1000) / safeSpeed;\n\n  const isPhone = device === \"phone\";\n  const deviceW = isPhone ? 320 : 760;\n  const deviceH = isPhone ? 640 : 470;\n  const screenInset = isPhone ? 12 : 18;\n  const bezelRadius = isPhone ? 36 : 14;\n\n  const containerStyle: CSSProperties = {\n    alignItems: \"center\",\n    background: \"radial-gradient(ellipse at center, #1a1a22 0%, #050507 70%)\",\n    display: \"flex\",\n    fontFamily: FONT_FAMILY,\n    height,\n    justifyContent: \"center\",\n    overflow: \"hidden\",\n    perspective: 2000,\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-hero-assemble-lid {\n            from { transform: translateZ(1000px); }\n            to { transform: translateZ(0); }\n          }\n          @keyframes framecn-hero-assemble-base {\n            from { transform: translateZ(-800px) rotateX(78deg); }\n            to { transform: translateZ(0) rotateX(0deg); }\n          }\n          @keyframes framecn-hero-assemble-bezel {\n            from { transform: translateZ(600px); }\n            to { transform: translateZ(0); }\n          }\n          @keyframes framecn-hero-assemble-screen {\n            from { transform: translateZ(300px); opacity: 0; }\n            to { transform: translateZ(0); opacity: 1; }\n          }\n          @keyframes framecn-hero-shimmer {\n            from { transform: translateX(-100%); }\n            to { transform: translateX(200%); }\n          }\n        `}</style>\n        <div\n          style={{\n            animation: `framecn-hero-assemble-lid ${assembleMs}ms cubic-bezier(0.16, 1, 0.3, 1) ${assembleDelayMs}ms backwards`,\n            height: deviceH,\n            position: \"relative\",\n            transformStyle: \"preserve-3d\",\n            width: deviceW,\n          }}\n        >\n          {/* Back lid */}\n          <div\n            style={{\n              animation: `framecn-hero-assemble-lid ${assembleMs}ms cubic-bezier(0.16, 1, 0.3, 1) ${assembleDelayMs}ms backwards`,\n              background: \"linear-gradient(180deg, #1f2128 0%, #0e1014 100%)\",\n              border: \"1px solid rgba(255,255,255,0.08)\",\n              borderRadius: bezelRadius + 4,\n              boxShadow:\n                \"0 60px 120px rgba(0,0,0,0.7), inset 0 1px 0 rgba(255,255,255,0.06)\",\n              inset: -4,\n              position: \"absolute\",\n            }}\n          />\n\n          {/* Keyboard / chassis base - laptop only */}\n          {!isPhone && (\n            <div\n              style={{\n                animation: `framecn-hero-assemble-base ${assembleMs}ms cubic-bezier(0.16, 1, 0.3, 1) ${assembleDelayMs}ms backwards`,\n                background: \"linear-gradient(180deg, #2a2d36 0%, #14161c 100%)\",\n                border: \"1px solid rgba(255,255,255,0.06)\",\n                borderRadius: \"0 0 12px 12px\",\n                bottom: -28,\n                boxShadow: \"0 30px 60px rgba(0,0,0,0.6)\",\n                height: 28,\n                left: -40,\n                position: \"absolute\",\n                right: -40,\n              }}\n            />\n          )}\n\n          {/* Bezel frame */}\n          <div\n            style={{\n              animation: `framecn-hero-assemble-bezel ${assembleMs}ms cubic-bezier(0.16, 1, 0.3, 1) ${assembleDelayMs}ms backwards`,\n              background: \"#0a0a0d\",\n              border: \"1px solid rgba(255,255,255,0.12)\",\n              borderRadius: bezelRadius,\n              boxShadow: \"inset 0 0 0 2px rgba(255,255,255,0.04)\",\n              inset: 0,\n              position: \"absolute\",\n            }}\n          />\n\n          {/* UI screen */}\n          <div\n            style={{\n              animation: `framecn-hero-assemble-screen ${assembleMs * 0.8}ms cubic-bezier(0.16, 1, 0.3, 1) ${assembleDelayMs + assembleMs * 0.2}ms backwards`,\n              background: \"black\",\n              borderRadius: bezelRadius - 6,\n              inset: screenInset,\n              overflow: \"hidden\",\n              position: \"absolute\",\n            }}\n          >\n            {/* Black panel during flight */}\n            <div\n              style={{\n                animation: `framecn-hero-assemble-screen ${settleMs}ms ease-out ${assembleDelayMs + assembleMs}ms forwards`,\n                inset: 0,\n                position: \"absolute\",\n              }}\n            />\n            {/* UI fades in */}\n            <div\n              style={{\n                animation: `framecn-hero-assemble-screen ${shimmerMs}ms ease-out ${assembleDelayMs + assembleMs + settleMs}ms backwards`,\n                inset: 0,\n                position: \"absolute\",\n              }}\n            >\n              <MockUI accentColor={accentColor} />\n            </div>\n            {/* Shimmer sweep */}\n            <div\n              style={{\n                animation: `framecn-hero-shimmer ${shimmerMs}ms ease-in-out ${assembleDelayMs + assembleMs + settleMs + 100}ms backwards`,\n                background:\n                  \"linear-gradient(115deg, transparent 40%, rgba(255,255,255,0.18) 50%, transparent 60%)\",\n                inset: 0,\n                mixBlendMode: \"screen\",\n                pointerEvents: \"none\",\n                position: \"absolute\",\n              }}\n            />\n          </div>\n        </div>\n      </>\n    </Timegroup>\n  );\n};\n",
      "type": "registry:component",
      "target": "components/framecn/hero-device-assemble.tsx"
    }
  ],
  "type": "registry:component"
}