{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "landing-code-showcase",
  "title": "Landing Code Showcase",
  "description": "Magical split-screen: code types itself on the left while the preview reactively re-renders on the right with sparks and tactile bounce.",
  "dependencies": [
    "remotion"
  ],
  "files": [
    {
      "path": "registry/bases/editframe/components/landing-code-showcase/index.tsx",
      "content": "\"use client\";\n\nimport { Timegroup } from \"@editframe/react\";\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\n/* -------------------------------------------------------------------------- */\n/*                                  Tokens                                    */\n/* -------------------------------------------------------------------------- */\n\nconst PEACH = \"#FFB38E\";\nconst LAVENDER = \"#D4B3FF\";\nconst MINT = \"#A1EEBD\";\nconst STAGE_BG = \"#0A090E\";\nconst PANEL_BG = \"#141318\";\n\n/* -------------------------------------------------------------------------- */\n/*                              Timeline (ms)                                 */\n/* -------------------------------------------------------------------------- */\n\nconst SCENES = {\n  blur: { duration: 3000, start: 0 },\n  dashboard: { duration: 3666, start: 4333 },\n  endHold: 2666,\n  glassWipe: { duration: 2000, start: 7666 },\n  maskedSlide: { duration: 4000, start: 9666 },\n  push1: { duration: 2000, start: 2333 },\n  push2: { duration: 2000, start: 13_333 },\n  terminal: { duration: 6000, start: 15_333 },\n};\n\nconst TOTAL_DURATION_MS =\n  SCENES.terminal.start + SCENES.terminal.duration + SCENES.endHold;\n\n/* -------------------------------------------------------------------------- */\n/*                              Code timeline                                 */\n/* -------------------------------------------------------------------------- */\n\ninterface CodeStep {\n  startMs: number;\n  code: string;\n  highlight?: string;\n}\n\nconst HEADER = `import { BlurReveal, DashboardPopulate, MaskedSlideReveal,\n  TerminalToBrowserDeploy, Transition } from \"@/components/framecn\";\n\nexport default function Scene() {\n  return (\n    <>\n`;\n\nconst FOOTER = `    </>\n  );\n}`;\n\nconst STEPS: CodeStep[] = [\n  { code: `      <BlurReveal text=\"Build faster.\" />\\n`, startMs: 133 },\n  {\n    code: `      <Transition type=\"spatial-push\" />\\n`,\n    highlight: \"spatial-push\",\n    startMs: SCENES.push1.start,\n  },\n  {\n    code: `      <DashboardPopulate data={metrics} />\\n`,\n    startMs: SCENES.dashboard.start,\n  },\n  {\n    code: `      <Transition type=\"glass-wipe\" />\\n`,\n    highlight: \"glass-wipe\",\n    startMs: SCENES.glassWipe.start,\n  },\n  {\n    code: `      <MaskedSlideReveal text=\"Ship to production.\" />\\n`,\n    startMs: SCENES.maskedSlide.start,\n  },\n  {\n    code: `      <Transition type=\"spatial-push\" direction=\"left\" />\\n`,\n    highlight: \"spatial-push\",\n    startMs: SCENES.push2.start,\n  },\n  {\n    code: `      <TerminalToBrowserDeploy />\\n`,\n    startMs: SCENES.terminal.start,\n  },\n];\n\nconst CHARS_PER_MS = 0.022;\n\n/* -------------------------------------------------------------------------- */\n/*                              Syntax highlight                              */\n/* -------------------------------------------------------------------------- */\n\ninterface Token {\n  text: string;\n  color: string;\n  glow?: boolean;\n}\n\nconst tokenizeLine = (\n  line: string,\n  accentColor: string,\n  highlightedToken: string | null\n): Token[] => {\n  const tokens: Token[] = [];\n  const regex =\n    /(\\bimport\\b|\\bfrom\\b|\\bexport\\b|\\bdefault\\b|\\bfunction\\b|\\breturn\\b|\\bconst\\b)|(\"[^\"]*\")|(\\b[A-Z][a-zA-Z0-9_]*)|(\\b[a-zA-Z_][a-zA-Z0-9_]*)(?==)|(\\{|\\}|\\(|\\)|<|>|\\/|;)|([0-9]+)/g;\n  let lastIndex = 0;\n  let m: RegExpExecArray | null = regex.exec(line);\n  while (m !== null) {\n    if (m.index > lastIndex) {\n      tokens.push({ color: \"#e4e4e7\", text: line.slice(lastIndex, m.index) });\n    }\n    if (m[1]) {\n      tokens.push({ color: LAVENDER, text: m[1] });\n    } else if (m[2]) {\n      const inner = m[2].slice(1, -1);\n      if (highlightedToken && inner === highlightedToken) {\n        tokens.push({ color: LAVENDER, glow: true, text: m[2] });\n      } else {\n        tokens.push({ color: MINT, text: m[2] });\n      }\n    } else if (m[3]) {\n      tokens.push({ color: PEACH, text: m[3] });\n    } else if (m[4]) {\n      tokens.push({ color: accentColor, text: m[4] });\n    } else if (m[5]) {\n      tokens.push({ color: \"#71717a\", text: m[5] });\n    } else if (m[6]) {\n      tokens.push({ color: \"#fbbf24\", text: m[6] });\n    }\n    ({ lastIndex } = regex);\n    m = regex.exec(line);\n  }\n  if (lastIndex < line.length) {\n    tokens.push({ color: \"#e4e4e7\", text: line.slice(lastIndex) });\n  }\n  return tokens;\n};\n\n/* -------------------------------------------------------------------------- */\n/*                                Code editor                                 */\n/* -------------------------------------------------------------------------- */\n\nconst CodeEditor = ({\n  elapsedMs,\n  accentColor,\n}: {\n  elapsedMs: number;\n  accentColor: string;\n}) => {\n  const dynamicChunks: string[] = [];\n  let activeHighlight: string | null = null;\n\n  for (const step of STEPS) {\n    if (elapsedMs < step.startMs) {\n      break;\n    }\n    const elapsed = elapsedMs - step.startMs;\n    const charsTyped = Math.min(\n      step.code.length,\n      Math.floor(elapsed * CHARS_PER_MS)\n    );\n    dynamicChunks.push(step.code.slice(0, charsTyped));\n    if (step.highlight) {\n      const sinceStart = elapsedMs - step.startMs;\n      if (sinceStart >= 0 && sinceStart < 2000) {\n        activeHighlight = step.highlight;\n      }\n    }\n  }\n\n  const allTyped = dynamicChunks.join(\"\");\n  const lastStep = STEPS.at(-1);\n  const showFooter =\n    lastStep !== undefined &&\n    elapsedMs > lastStep.startMs + lastStep.code.length / CHARS_PER_MS + 133;\n  const visibleCode = HEADER + allTyped + (showFooter ? FOOTER : \"\");\n  const lines = visibleCode.split(\"\\n\");\n  const lastLineIdx = lines.length - 1;\n  const caretOn = Math.floor(elapsedMs / 400) % 2 === 0;\n\n  return (\n    <div\n      style={{\n        background:\n          \"linear-gradient(180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.02) 50%, rgba(255,255,255,0.06) 100%)\",\n        borderRadius: 16,\n        boxShadow: \"0 40px 90px rgba(0,0,0,0.55), 0 0 0 1px rgba(0,0,0,0.4)\",\n        maxWidth: 540,\n        padding: 1,\n        position: \"relative\",\n        width: \"100%\",\n      }}\n    >\n      <div\n        style={{\n          backdropFilter: \"blur(20px)\",\n          background: \"rgba(12,12,14,0.9)\",\n          borderRadius: 15,\n          overflow: \"hidden\",\n        }}\n      >\n        {/* Title bar */}\n        <div\n          style={{\n            alignItems: \"center\",\n            borderBottom: \"1px solid rgba(255,255,255,0.06)\",\n            display: \"flex\",\n            gap: 8,\n            height: 40,\n            padding: \"0 16px\",\n          }}\n        >\n          {[\"#ff5f57\", \"#febc2e\", \"#28c840\"].map((c) => (\n            <div\n              key={c}\n              style={{\n                background: c,\n                borderRadius: 6,\n                height: 11,\n                opacity: 0.65,\n                width: 11,\n              }}\n            />\n          ))}\n          <div\n            style={{\n              color: \"rgba(255,255,255,0.5)\",\n              fontFamily: MONO_FAMILY,\n              fontSize: 12,\n              marginLeft: 12,\n            }}\n          >\n            scene.tsx\n          </div>\n        </div>\n\n        {/* Code body */}\n        <div\n          style={{\n            boxShadow: \"inset 0 1px 0 rgba(255,255,255,0.04)\",\n            color: \"#e4e4e7\",\n            fontFamily: MONO_FAMILY,\n            fontSize: 12.5,\n            lineHeight: 1.7,\n            minHeight: 480,\n            padding: \"20px 22px\",\n          }}\n        >\n          {lines.map((line, i) => {\n            const tokens = tokenizeLine(line, accentColor, activeHighlight);\n            const isLast = i === lastLineIdx;\n            return (\n              <div key={i} style={{ display: \"flex\", whiteSpace: \"pre\" }}>\n                <span\n                  style={{\n                    color: \"rgba(255,255,255,0.18)\",\n                    flexShrink: 0,\n                    userSelect: \"none\",\n                    width: 26,\n                  }}\n                >\n                  {i + 1}\n                </span>\n                <span>\n                  {tokens.length === 0 ? (\n                    <span> </span>\n                  ) : (\n                    tokens.map((t, j) => (\n                      <span\n                        key={j}\n                        style={{\n                          color: t.color,\n                          textShadow: t.glow\n                            ? `0 0 12px ${LAVENDER}, 0 0 24px ${LAVENDER}80`\n                            : undefined,\n                        }}\n                      >\n                        {t.text}\n                      </span>\n                    ))\n                  )}\n                  {isLast && caretOn && (\n                    <span\n                      style={{\n                        background: accentColor,\n                        display: \"inline-block\",\n                        height: 14,\n                        marginLeft: 1,\n                        verticalAlign: \"text-bottom\",\n                        width: 7,\n                      }}\n                    />\n                  )}\n                </span>\n              </div>\n            );\n          })}\n        </div>\n      </div>\n    </div>\n  );\n};\n\n/* -------------------------------------------------------------------------- */\n/*                                Main component                              */\n/* -------------------------------------------------------------------------- */\n\nexport interface LandingCodeShowcaseProps {\n  accentColor?: string;\n  speed?: number;\n}\n\nexport const LandingCodeShowcase = ({\n  accentColor = \"#FFB38E\",\n  speed = 1,\n}: LandingCodeShowcaseProps) => {\n  const safeSpeed = Math.max(0.01, speed);\n\n  return (\n    <Timegroup\n      duration={`${TOTAL_DURATION_MS / safeSpeed}ms`}\n      mode=\"fixed\"\n      style={{\n        background: PANEL_BG,\n        fontFamily: FONT_FAMILY,\n        height: 720,\n        overflow: \"hidden\",\n        position: \"relative\",\n        width: 1280,\n      }}\n    >\n      <style>{`\n        @keyframes framecn-lcs-blur {\n          from { opacity: 0; filter: blur(22px); }\n          to { opacity: 1; filter: blur(0px); }\n        }\n        @keyframes framecn-lcs-glow {\n          0%, 70% { box-shadow: inset 0 0 0px rgba(161,238,189,0); }\n          100% { box-shadow: inset 0 0 60px rgba(161,238,189,0.45); }\n        }\n        @keyframes framecn-lcs-push-up {\n          from { transform: translateY(0%); }\n          to { transform: translateY(-110%); }\n        }\n        @keyframes framecn-lcs-push-left {\n          from { transform: translateX(0%); }\n          to { transform: translateX(-110%); }\n        }\n        @keyframes framecn-lcs-glass {\n          from { opacity: 1; backdrop-filter: blur(0px); }\n          to { opacity: 0; backdrop-filter: blur(28px); }\n        }\n      `}</style>\n\n      {/* Backdrop wash */}\n      <div\n        style={{\n          background:\n            \"radial-gradient(ellipse at 20% 30%, rgba(255,179,142,0.06), transparent 55%), radial-gradient(ellipse at 80% 70%, rgba(212,179,255,0.06), transparent 55%)\",\n          inset: 0,\n          position: \"absolute\",\n        }}\n      />\n\n      {/* LEFT: Code editor */}\n      <div\n        style={{\n          alignItems: \"center\",\n          bottom: 0,\n          display: \"flex\",\n          justifyContent: \"center\",\n          left: 0,\n          padding: 48,\n          position: \"absolute\",\n          top: 0,\n          width: \"38%\",\n        }}\n      >\n        <CodeEditor\n          elapsedMs={(TOTAL_DURATION_MS / safeSpeed) * 0.5}\n          accentColor={accentColor}\n        />\n      </div>\n\n      {/* RIGHT: Live preview */}\n      <div\n        style={{\n          borderLeft: \"1px solid rgba(255,255,255,0.05)\",\n          bottom: 0,\n          position: \"absolute\",\n          right: 0,\n          top: 0,\n          width: \"62%\",\n        }}\n      >\n        {/* Preview label */}\n        <div\n          style={{\n            alignItems: \"center\",\n            display: \"flex\",\n            gap: 8,\n            left: 24,\n            position: \"absolute\",\n            top: 22,\n            zIndex: 5,\n          }}\n        >\n          <div\n            style={{\n              background: MINT,\n              borderRadius: 4,\n              height: 8,\n              width: 8,\n            }}\n          />\n          <div\n            style={{\n              color: \"rgba(255,255,255,0.5)\",\n              fontFamily: MONO_FAMILY,\n              fontSize: 11,\n              letterSpacing: \"0.1em\",\n              textTransform: \"uppercase\",\n            }}\n          >\n            Preview · HMR\n          </div>\n        </div>\n\n        <div\n          style={{\n            animation: `framecn-lcs-glow ${TOTAL_DURATION_MS / safeSpeed}ms ease-out forwards`,\n            inset: 0,\n            overflow: \"hidden\",\n            position: \"absolute\",\n          }}\n        >\n          {/* BlurReveal scene */}\n          <div\n            style={{\n              alignItems: \"center\",\n              animation: `framecn-lcs-blur ${SCENES.blur.duration}ms ease-out forwards`,\n              background: STAGE_BG,\n              display: \"flex\",\n              inset: 0,\n              justifyContent: \"center\",\n              position: \"absolute\",\n            }}\n          >\n            <span\n              style={{\n                color: PEACH,\n                fontFamily: FONT_FAMILY,\n                fontSize: 96,\n                fontWeight: 600,\n                letterSpacing: \"-0.04em\",\n              }}\n            >\n              Build faster.\n            </span>\n          </div>\n\n          {/* SpatialPush up transition overlay */}\n          <div\n            style={{\n              alignItems: \"center\",\n              animation: `framecn-lcs-push-up ${SCENES.push1.duration}ms ease-in ${SCENES.push1.start}ms forwards`,\n              background: STAGE_BG,\n              display: \"flex\",\n              inset: 0,\n              justifyContent: \"center\",\n              position: \"absolute\",\n            }}\n          >\n            <span\n              style={{\n                color: MINT,\n                fontFamily: FONT_FAMILY,\n                fontSize: 96,\n                fontWeight: 700,\n              }}\n            >\n              Dashboard\n            </span>\n          </div>\n\n          {/* Dashboard scene */}\n          <div\n            style={{\n              animation: `framecn-lcs-glass ${SCENES.glassWipe.duration}ms ease-in ${SCENES.glassWipe.start}ms forwards`,\n              background: STAGE_BG,\n              inset: 0,\n              position: \"absolute\",\n            }}\n          />\n\n          {/* MaskedSlide scene */}\n          <div\n            style={{\n              alignItems: \"center\",\n              animation: `framecn-lcs-push-left ${SCENES.push2.duration}ms ease-in ${SCENES.push2.start}ms forwards`,\n              background: STAGE_BG,\n              display: \"flex\",\n              inset: 0,\n              justifyContent: \"center\",\n              position: \"absolute\",\n            }}\n          >\n            <span\n              style={{\n                color: MINT,\n                fontFamily: FONT_FAMILY,\n                fontSize: 92,\n                fontWeight: 700,\n              }}\n            >\n              Ship to production.\n            </span>\n          </div>\n\n          {/* Terminal scene */}\n          <div\n            style={{\n              alignItems: \"center\",\n              background: STAGE_BG,\n              display: \"flex\",\n              inset: 0,\n              justifyContent: \"center\",\n              position: \"absolute\",\n            }}\n          >\n            <span\n              style={{\n                color: PEACH,\n                fontFamily: FONT_FAMILY,\n                fontSize: 96,\n                fontWeight: 700,\n              }}\n            >\n              Deploy ✓\n            </span>\n          </div>\n        </div>\n      </div>\n    </Timegroup>\n  );\n};\n\n// Re-export the schedule so config.ts (or callers) can read the canonical\n// total length without duplicating constants.\nexport const LANDING_CODE_SHOWCASE_DURATION = Math.round(\n  TOTAL_DURATION_MS / 30\n);\n",
      "type": "registry:component",
      "target": "components/framecn/landing-code-showcase.tsx"
    }
  ],
  "type": "registry:component"
}