{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "browser-flow",
  "title": "Browser Flow",
  "description": "Full Safari/Chrome simulation: typed URL, progress bar, page render, scroll, and a virtual cursor click.",
  "dependencies": [
    "remotion"
  ],
  "files": [
    {
      "path": "registry/bases/editframe/components/browser-flow/index.tsx",
      "content": "\"use client\";\n\nimport { Timegroup } from \"@editframe/react\";\nimport type { CSSProperties } from \"react\";\n\nexport interface BrowserFlowProps {\n  url?: string;\n  speed?: number;\n  background?: string;\n  className?: string;\n  fps?: number;\n  durationInFrames?: number;\n  width?: number;\n  height?: number;\n}\n\nconst FONT_FAMILY =\n  \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\";\nconst MONO_FAMILY =\n  \"var(--font-geist-mono), ui-monospace, SFMono-Regular, Menlo, monospace\";\n\nconst MacDots = ({ size = 12 }: { size?: number }) => (\n  <div style={{ alignItems: \"center\", display: \"flex\", gap: 8 }}>\n    {[\"#ff5f57\", \"#febc2e\", \"#28c840\"].map((c) => (\n      <div\n        key={c}\n        style={{\n          background: c,\n          borderRadius: \"50%\",\n          height: size,\n          opacity: 0.85,\n          width: size,\n        }}\n      />\n    ))}\n  </div>\n);\n\nexport const BrowserFlow = ({\n  url = \"framecn.dev\",\n  speed = 1,\n  background = \"white\",\n  className,\n  fps = 30,\n  durationInFrames = 270,\n  width = 1280,\n  height = 720,\n}: BrowserFlowProps) => {\n  const safeSpeed = Math.max(0.01, speed);\n  const durationMs = (durationInFrames / fps) * 1000;\n  const frameMs = 1000 / fps;\n\n  // Animation timing (converted from frames)\n  const typingStartMs = 4 * frameMs;\n  const typingEndMs = 38 * frameMs;\n  const typingDurationMs = (typingEndMs - typingStartMs) / safeSpeed;\n\n  const progressStartMs = 40 * frameMs;\n  const progressEndMs = 95 * frameMs;\n\n  const pageStartMs = 95 * frameMs;\n  const pageFadeDurationMs = 12 * frameMs;\n\n  const scrollStartMs = 115 * frameMs;\n  const scrollEndMs = 230 * frameMs;\n  const scrollDurationMs = (scrollEndMs - scrollStartMs) / safeSpeed;\n\n  const clickMs = (230 + 4) * frameMs;\n\n  const containerStyle: CSSProperties = {\n    background: \"radial-gradient(ellipse at center, #11141c 0%, #050505 75%)\",\n    fontFamily: FONT_FAMILY,\n    height,\n    overflow: \"hidden\",\n    position: \"relative\",\n    width,\n  };\n\n  const browserWidth = 1100;\n  const browserHeight = 620;\n  const chromeHeight = 56;\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-browser-type {\n            from { width: 0ch; }\n            to { width: ${url.length}ch; }\n          }\n          @keyframes framecn-browser-cursor {\n            0%, 50% { opacity: 1; }\n            50.01%, 100% { opacity: 0; }\n          }\n          @keyframes framecn-browser-progress {\n            0% { width: 0%; }\n            23.5% { width: 15%; }\n            58.8% { width: 15%; }\n            100% { width: 100%; }\n          }\n          @keyframes framecn-browser-progress-fade {\n            to { opacity: 0; }\n          }\n          @keyframes framecn-browser-page {\n            from { opacity: 0; }\n            to { opacity: 1; }\n          }\n          @keyframes framecn-browser-scroll {\n            from { transform: translateY(0); }\n            to { transform: translateY(-600px); }\n          }\n          @keyframes framecn-browser-cursor-move {\n            0% { left: 380px; top: ${chromeHeight + 60}px; }\n            100% { left: 50%; top: ${chromeHeight + 380}px; }\n          }\n          @keyframes framecn-browser-click {\n            0%, 40% { transform: scale(1); }\n            50%, 100% { transform: scale(0.85); }\n          }\n          @keyframes framecn-browser-btn-click {\n            0%, 40% { transform: scale(1); }\n            50%, 100% { transform: scale(0.98); }\n          }\n        `}</style>\n        <div\n          style={{\n            background: \"#0a0a0c\",\n            border: \"1px solid rgba(255,255,255,0.08)\",\n            borderRadius: 16,\n            boxShadow:\n              \"0 50px 120px rgba(0,0,0,0.7), inset 0 1px 0 rgba(255,255,255,0.06)\",\n            height: browserHeight,\n            left: (width - browserWidth) / 2,\n            overflow: \"hidden\",\n            position: \"absolute\",\n            top: (height - browserHeight) / 2,\n            width: browserWidth,\n          }}\n        >\n          {/* Chrome */}\n          <div\n            style={{\n              alignItems: \"center\",\n              background: \"rgba(20,20,24,0.95)\",\n              borderBottom: \"1px solid rgba(255,255,255,0.06)\",\n              display: \"flex\",\n              gap: 14,\n              height: chromeHeight,\n              paddingLeft: 18,\n              paddingRight: 18,\n              position: \"relative\",\n            }}\n          >\n            <MacDots />\n            <div\n              style={{\n                color: \"rgba(255,255,255,0.35)\",\n                display: \"flex\",\n                fontSize: 16,\n                gap: 6,\n                marginLeft: 8,\n              }}\n            >\n              <span>‹</span>\n              <span>›</span>\n            </div>\n            <div\n              style={{\n                alignItems: \"center\",\n                background: \"rgba(255,255,255,0.08)\",\n                border: \"1px solid rgba(120,160,255,0.45)\",\n                borderRadius: 16,\n                boxShadow: \"0 0 0 3px rgba(120,160,255,0.12)\",\n                color: \"rgba(255,255,255,0.85)\",\n                display: \"flex\",\n                flex: 1,\n                fontFamily: MONO_FAMILY,\n                fontSize: 13,\n                height: 32,\n                paddingLeft: 14,\n                paddingRight: 14,\n                position: \"relative\",\n              }}\n            >\n              <span style={{ color: \"rgba(255,255,255,0.4)\", marginRight: 8 }}>\n                ⌕\n              </span>\n              <span\n                style={{\n                  animation: `framecn-browser-type ${typingDurationMs}ms steps(${url.length}) ${typingStartMs}ms backwards`,\n                  overflow: \"hidden\",\n                  whiteSpace: \"nowrap\",\n                }}\n              >\n                {url}\n              </span>\n              <span\n                style={{\n                  animation: `framecn-browser-cursor 1000ms ease-in-out infinite ${typingStartMs}ms`,\n                  background: \"rgba(255,255,255,0.85)\",\n                  display: \"inline-block\",\n                  height: 16,\n                  marginLeft: 1,\n                  width: 1.5,\n                }}\n              />\n            </div>\n            <div style={{ width: 60 }} />\n\n            {/* Progress bar */}\n            <div\n              style={{\n                animation: `framecn-browser-progress-fade ${durationMs - progressEndMs}ms ease-out ${progressEndMs}ms forwards`,\n                bottom: 0,\n                height: 2,\n                left: 0,\n                position: \"absolute\",\n                right: 0,\n              }}\n            >\n              <div\n                style={{\n                  animation: `framecn-browser-progress ${progressEndMs - progressStartMs}ms ease-out ${progressStartMs}ms backwards`,\n                  background:\n                    \"linear-gradient(90deg, #3b82f6 0%, #60a5fa 100%)\",\n                  boxShadow: \"0 0 8px rgba(96,165,250,0.6)\",\n                  height: \"100%\",\n                  transformOrigin: \"left\",\n                  width: \"100%\",\n                }}\n              />\n            </div>\n          </div>\n\n          {/* Page viewport */}\n          <div\n            style={{\n              background: \"#0a0a0c\",\n              bottom: 0,\n              left: 0,\n              overflow: \"hidden\",\n              position: \"absolute\",\n              right: 0,\n              top: chromeHeight,\n            }}\n          >\n            <div\n              style={{\n                animation: `framecn-browser-page ${pageFadeDurationMs}ms ease-out ${pageStartMs}ms backwards`,\n              }}\n            >\n              <div\n                style={{\n                  animation: `framecn-browser-scroll ${scrollDurationMs}ms cubic-bezier(0.16, 1, 0.3, 1) ${scrollStartMs}ms backwards`,\n                }}\n              >\n                {/* Header */}\n                <div\n                  style={{\n                    alignItems: \"center\",\n                    borderBottom: \"1px solid rgba(255,255,255,0.05)\",\n                    display: \"flex\",\n                    height: 68,\n                    justifyContent: \"space-between\",\n                    padding: \"0 60px\",\n                  }}\n                >\n                  <div\n                    style={{\n                      color: \"white\",\n                      fontSize: 18,\n                      fontWeight: 700,\n                      letterSpacing: \"-0.02em\",\n                    }}\n                  >\n                    framecn\n                  </div>\n                  <div\n                    style={{\n                      color: \"rgba(255,255,255,0.65)\",\n                      display: \"flex\",\n                      fontSize: 14,\n                      gap: 28,\n                    }}\n                  >\n                    <span>Components</span>\n                    <span>Docs</span>\n                    <span>GitHub</span>\n                  </div>\n                </div>\n\n                {/* Hero */}\n                <div\n                  style={{\n                    alignItems: \"center\",\n                    display: \"flex\",\n                    flexDirection: \"column\",\n                    gap: 24,\n                    padding: \"100px 60px 80px\",\n                    textAlign: \"center\",\n                  }}\n                >\n                  <div\n                    style={{\n                      color: \"rgba(120,160,255,0.85)\",\n                      fontSize: 13,\n                      fontWeight: 500,\n                      letterSpacing: \"0.02em\",\n                    }}\n                  >\n                    shadcn registry for Editframe\n                  </div>\n                  <div\n                    style={{\n                      color: \"white\",\n                      fontSize: 64,\n                      fontWeight: 700,\n                      letterSpacing: \"-0.04em\",\n                      lineHeight: 1.05,\n                      maxWidth: 720,\n                    }}\n                  >\n                    Production-ready video blocks.\n                  </div>\n                  <div\n                    style={{\n                      color: \"rgba(255,255,255,0.6)\",\n                      fontSize: 17,\n                      lineHeight: 1.5,\n                      maxWidth: 520,\n                    }}\n                  >\n                    Drop-in animations, transitions, and backgrounds for\n                    Editframe. Own your code.\n                  </div>\n\n                  {/* CTA */}\n                  <button\n                    type=\"button\"\n                    style={{\n                      animation: `framecn-browser-btn-click 300ms cubic-bezier(0.16, 1, 0.3, 1) ${clickMs}ms backwards`,\n                      background,\n                      border: \"none\",\n                      borderRadius: 12,\n                      boxShadow: \"0 10px 30px rgba(255,255,255,0.1)\",\n                      color: \"#0a0a0c\",\n                      fontFamily: FONT_FAMILY,\n                      fontSize: 15,\n                      fontWeight: 600,\n                      marginTop: 12,\n                      padding: \"16px 32px\",\n                    }}\n                  >\n                    Browse components →\n                  </button>\n                </div>\n\n                {/* Sections */}\n                {[\n                  { color: \"#3b82f6\", title: \"Typography\" },\n                  { color: \"#a855f7\", title: \"Backgrounds\" },\n                  { color: \"#22c55e\", title: \"Transitions\" },\n                ].map((s) => (\n                  <div\n                    key={s.title}\n                    style={{\n                      alignItems: \"center\",\n                      background:\n                        \"linear-gradient(180deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.01) 100%)\",\n                      border: \"1px solid rgba(255,255,255,0.06)\",\n                      borderRadius: 16,\n                      display: \"flex\",\n                      gap: 28,\n                      margin: \"40px 60px\",\n                      padding: \"40px\",\n                    }}\n                  >\n                    <div\n                      style={{\n                        background: `${s.color}22`,\n                        border: `1px solid ${s.color}55`,\n                        borderRadius: 14,\n                        height: 64,\n                        width: 64,\n                      }}\n                    />\n                    <div\n                      style={{\n                        display: \"flex\",\n                        flexDirection: \"column\",\n                        gap: 6,\n                      }}\n                    >\n                      <div\n                        style={{\n                          color: \"white\",\n                          fontSize: 22,\n                          fontWeight: 600,\n                          letterSpacing: \"-0.02em\",\n                        }}\n                      >\n                        {s.title}\n                      </div>\n                      <div\n                        style={{\n                          color: \"rgba(255,255,255,0.55)\",\n                          fontSize: 14,\n                        }}\n                      >\n                        Hand-tuned primitives, copied straight into your\n                        project.\n                      </div>\n                    </div>\n                  </div>\n                ))}\n              </div>\n            </div>\n          </div>\n        </div>\n\n        {/* Virtual cursor */}\n        <div\n          style={{\n            animation: `framecn-browser-cursor-move ${scrollDurationMs + 300}ms cubic-bezier(0.16, 1, 0.3, 1) ${scrollStartMs}ms backwards`,\n            filter: \"drop-shadow(0 4px 8px rgba(0,0,0,0.5))\",\n            height: 28,\n            position: \"absolute\",\n            transformOrigin: \"top left\",\n            width: 22,\n            zIndex: 9999,\n          }}\n        >\n          <svg width=\"22\" height=\"28\" viewBox=\"0 0 22 28\" fill=\"none\">\n            <path\n              d=\"M2 2L2 22L7 17.5L10.5 25L13.5 23.5L10 16L17 16L2 2Z\"\n              fill=\"white\"\n              stroke=\"black\"\n              strokeWidth=\"1.5\"\n              strokeLinejoin=\"round\"\n            />\n          </svg>\n        </div>\n      </>\n    </Timegroup>\n  );\n};\n",
      "type": "registry:component",
      "target": "components/framecn/browser-flow.tsx"
    }
  ],
  "type": "registry:component"
}