> ## Documentation Index
> Fetch the complete documentation index at: https://docs.replit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Canvas

> Learn how to use the Canvas to explore and iterate on designs with Agent, and see your artifacts displayed in frames.

export const WistiaEmbed = ({videoId, title = "Wistia video", playerColor = "FF0000", controlsVisibleOnLoad = false}) => {
  if (!videoId) {
    return null;
  }
  const url = "https://fast.wistia.net/embed/iframe/" + videoId + "?seo=false&playerColor=" + playerColor + "&controlsVisibleOnLoad=" + controlsVisibleOnLoad;
  return <Frame>
      <iframe src={url} title={title} allow="autoplay; fullscreen" allowFullScreen></iframe>
    </Frame>;
};

export const AgentCarousel = ({correctChoice = ""}) => {
  const outputTypes = [{
    name: "Web",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M12 1.25c5.937 0 10.75 4.813 10.75 10.75S17.937 22.75 12 22.75 1.25 17.937 1.25 12 6.063 1.25 12 1.25Zm-9.217 11.5a9.25 9.25 0 0 0 7.468 8.333 15.25 15.25 0 0 1-2.982-8.333H2.783Zm13.948 0a15.249 15.249 0 0 1-2.983 8.333 9.25 9.25 0 0 0 7.469-8.333H16.73Zm-7.958 0A13.748 13.748 0 0 0 12 20.876a13.748 13.748 0 0 0 3.227-8.126H8.773Zm1.478-9.834a9.251 9.251 0 0 0-7.468 8.334H7.27a15.251 15.251 0 0 1 2.982-8.334ZM12 3.123a13.747 13.747 0 0 0-3.227 8.127h6.454A13.748 13.748 0 0 0 12 3.123Zm1.748-.207a15.25 15.25 0 0 1 2.983 8.334h4.486a9.251 9.251 0 0 0-7.469-8.334Z" clip-rule="evenodd" /></svg>'
  }, {
    name: "Mobile",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M7 2.75c-.69 0-1.25.56-1.25 1.25v16c0 .69.56 1.25 1.25 1.25h10c.69 0 1.25-.56 1.25-1.25V4c0-.69-.56-1.25-1.25-1.25H7ZM4.25 4A2.75 2.75 0 0 1 7 1.25h10A2.75 2.75 0 0 1 19.75 4v16A2.75 2.75 0 0 1 17 22.75H7A2.75 2.75 0 0 1 4.25 20V4Zm7 14a.75.75 0 0 1 .75-.75h.01a.75.75 0 0 1 0 1.5H12a.75.75 0 0 1-.75-.75Z" clip-rule="evenodd" /></svg>'
  }, {
    name: "Slides",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M20 2.25A2.75 2.75 0 0 1 22.75 5v14A2.75 2.75 0 0 1 20 21.75h-8A2.75 2.75 0 0 1 9.25 19V5A2.75 2.75 0 0 1 12 2.25h8Zm-8 1.5c-.69 0-1.25.56-1.25 1.25v14c0 .69.56 1.25 1.25 1.25h8c.69 0 1.25-.56 1.25-1.25V5c0-.69-.56-1.25-1.25-1.25h-8Z" clip-rule="evenodd" /><path d="M6 4.25a.75.75 0 0 1 .75.75v14a.75.75 0 0 1-1.5 0V5A.75.75 0 0 1 6 4.25ZM2 6.25a.75.75 0 0 1 .75.75v10a.75.75 0 0 1-1.5 0V7A.75.75 0 0 1 2 6.25Z" /></svg>'
  }, {
    name: "Animation",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M10.024 7.25c.31.004.613.091.878.251l4.996 2.996a1.752 1.752 0 0 1 .625 2.367 1.75 1.75 0 0 1-.625.639v-.001l-4.995 2.995.001.001a1.75 1.75 0 0 1-2.654-1.505v-5.99a1.75 1.75 0 0 1 1.774-1.753Zm-.02 1.5a.252.252 0 0 0-.22.124.253.253 0 0 0-.034.127v5.998a.252.252 0 0 0 .127.219.253.253 0 0 0 .252-.004l.002-.001 4.997-2.997.002-.001a.252.252 0 0 0 .122-.215.25.25 0 0 0-.122-.215h-.002L10.13 8.786h-.002a.25.25 0 0 0-.125-.037Z" clip-rule="evenodd" /><path fill-rule="evenodd" d="M12 1.25c5.937 0 10.75 4.813 10.75 10.75S17.937 22.75 12 22.75 1.25 17.937 1.25 12 6.063 1.25 12 1.25Zm0 1.5a9.25 9.25 0 1 0 0 18.5 9.25 9.25 0 0 0 0-18.5Z" clip-rule="evenodd" /></svg>'
  }, {
    name: "Design",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M6.5 11.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM17.5 9.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM8.5 6.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM13.5 5.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5Z" /><path fill-rule="evenodd" d="M12 1.25c2.827 0 5.553 1.01 7.573 2.828C21.596 5.9 22.75 8.388 22.75 11A5.749 5.749 0 0 1 17 16.75h-2.25a1 1 0 0 0-.8 1.6l.3.4.1.143a2.5 2.5 0 0 1-2.1 3.857H12a10.75 10.75 0 1 1 0-21.5Zm0 1.5a9.25 9.25 0 1 0 0 18.5h.25a1 1 0 0 0 .8-1.6l-.3-.4a2.5 2.5 0 0 1 2-4H17l.21-.005A4.25 4.25 0 0 0 21.25 11c0-2.161-.953-4.252-2.68-5.807C16.84 3.636 14.476 2.75 12 2.75Z" clip-rule="evenodd" /></svg>'
  }, {
    name: "Data Visualization",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M5 14.25a.75.75 0 0 1 .75.75v6a.75.75 0 0 1-1.5 0v-6a.75.75 0 0 1 .75-.75ZM12 8.25a.75.75 0 0 1 .75.75v12a.75.75 0 0 1-1.5 0V9a.75.75 0 0 1 .75-.75ZM19 2.25a.75.75 0 0 1 .75.75v18a.75.75 0 0 1-1.5 0V3a.75.75 0 0 1 .75-.75Z" /></svg>'
  }, {
    name: "Automation",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M13.376 1.253c.21-.02.422.012.616.096l.095.046.091.053c.178.115.323.274.423.46l.045.096.038.099a1.25 1.25 0 0 1 .01.755l-1.92 6.02c-.003.011-.007.023-.012.034a.253.253 0 0 0 .03.23.25.25 0 0 0 .206.108H20l.123.004a1.752 1.752 0 0 1 1.24 2.849.73.73 0 0 1-.045.05l-9.9 10.199v-.001a1.25 1.25 0 0 1-2.122-1.18l.01-.03 1.92-6.019.012-.035a.251.251 0 0 0-.12-.309.255.255 0 0 0-.056-.02l-.06-.008H4a1.752 1.752 0 0 1-1.363-2.852l.045-.05 9.9-10.2a1.25 1.25 0 0 1 .689-.38l.104-.015Zm-9.582 11.6a.252.252 0 0 0-.023.255.25.25 0 0 0 .227.142h7.001l.21.013a1.75 1.75 0 0 1 1.53 1.518c.034.269.003.54-.086.795l.002.001-1.591 4.986 9.14-9.418a.249.249 0 0 0 .047-.116.252.252 0 0 0-.115-.24.249.249 0 0 0-.064-.03l-.07-.009H13a1.753 1.753 0 0 1-1.74-1.531 1.752 1.752 0 0 1 .086-.797l1.588-4.985-9.14 9.417Z" clip-rule="evenodd" /></svg>'
  }, {
    name: "3D Game",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M11.25 9.675A3.751 3.751 0 0 1 12 2.25a3.75 3.75 0 0 1 .75 7.425v4.575H19A2.75 2.75 0 0 1 21.75 17v2A2.75 2.75 0 0 1 19 21.75H5A2.75 2.75 0 0 1 2.25 19v-2A2.75 2.75 0 0 1 5 14.25h.25V13a.75.75 0 0 1 1.5 0v1.25h4.5V9.675ZM9.75 6a2.25 2.25 0 1 0 4.5 0 2.25 2.25 0 0 0-4.5 0ZM4.116 16.116A1.25 1.25 0 0 1 5 15.75h14A1.25 1.25 0 0 1 20.25 17v2A1.25 1.25 0 0 1 19 20.25H5a1.25 1.25 0 0 1-1.244-1.126L3.75 19v-2c0-.331.132-.65.366-.884Z" clip-rule="evenodd" /></svg>'
  }, {
    name: "Document",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M11.88 11.251a2.873 2.873 0 0 1 2.028 4.904L8.89 21.168a2.75 2.75 0 0 1-1.174.694l-2.867.838a1.255 1.255 0 0 1-1.234-.316 1.251 1.251 0 0 1-.316-1.235l.836-2.868c.13-.443.37-.847.696-1.174l5.017-5.015a2.875 2.875 0 0 1 2.032-.841Zm-.001 1.5c-.319 0-.626.11-.87.31l-.1.091L5.89 18.17a1.251 1.251 0 0 0-.315.532l-.709 2.43 2.43-.708a1.25 1.25 0 0 0 .533-.317l5.019-5.012a1.372 1.372 0 0 0-.97-2.343Z" clip-rule="evenodd" /><path fill-rule="evenodd" d="M14.038 1.251a3.148 3.148 0 0 1 2.198.925l3.587 3.587A3.152 3.152 0 0 1 20.75 8v12A2.75 2.75 0 0 1 18 22.75h-5.341a.75.75 0 0 1 0-1.5h5.34A1.25 1.25 0 0 0 19.25 20V8.75H15A1.75 1.75 0 0 1 13.25 7V2.75H6A1.25 1.25 0 0 0 4.75 4v9.34a.75.75 0 1 1-1.5 0V4A2.75 2.75 0 0 1 6 1.25h8l.039.001ZM14.75 7a.25.25 0 0 0 .25.25h4.071a1.65 1.65 0 0 0-.306-.425l-3.59-3.59a1.655 1.655 0 0 0-.425-.307V7Z" clip-rule="evenodd" /></svg>'
  }, {
    name: "Spreadsheet",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M21.75 6A3.75 3.75 0 0 0 18 2.25H6A3.75 3.75 0 0 0 2.25 6v12A3.75 3.75 0 0 0 6 21.75h12A3.75 3.75 0 0 0 21.75 18V6ZM18 3.75A2.25 2.25 0 0 1 20.25 6v2.25H9.75v-4.5H18Zm-9.75 0v4.5h-4.5V6A2.25 2.25 0 0 1 6 3.75h2.25Zm-4.5 6h4.5v4.5h-4.5v-4.5Zm0 6h4.5v4.5H6A2.25 2.25 0 0 1 3.75 18v-2.25Zm6 4.5v-4.5h10.5V18A2.25 2.25 0 0 1 18 20.25H9.75Zm10.5-6H9.75v-4.5h10.5v4.5Z" clip-rule="evenodd" /></svg>'
  }];
  const ITEMS_PER_PAGE = 5;
  const ITEM_WIDTH = 96;
  const VISIBLE_WIDTH = ITEMS_PER_PAGE * ITEM_WIDTH;
  const trackId = "ac-carousel-track";
  const checkSvg = '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M20.53 5.47a.75.75 0 0 1 0 1.06l-11 11a.75.75 0 0 1-1.06 0l-5-5a.75.75 0 1 1 1.06-1.06L9 15.94 19.47 5.47a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" /></svg>';
  const updateHint = selectedName => {
    const hintEl = document.getElementById("ac-carousel-hint");
    if (!hintEl || !correctChoice) return;
    if (!selectedName) {
      hintEl.innerHTML = "";
      return;
    }
    if (selectedName === correctChoice) {
      hintEl.innerHTML = `<span class="ac-hint ac-hint-correct"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" style="vertical-align:-2px;margin-right:4px"><path fill-rule="evenodd" d="M20.53 5.47a.75.75 0 0 1 0 1.06l-11 11a.75.75 0 0 1-1.06 0l-5-5a.75.75 0 1 1 1.06-1.06L9 15.94 19.47 5.47a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" /></svg>Great choice!</span>`;
    } else {
      hintEl.innerHTML = `<span class="ac-hint ac-hint-nudge">You can build anything you want! For this quickstart, try selecting <strong>${correctChoice}</strong>.</span>`;
    }
  };
  const toggleOutputType = name => {
    const btn = document.querySelector(`.agent-carousel-wrap [data-option-name="${name}"]`);
    const pillsContainer = document.getElementById("agent-input-pills");
    if (!btn) return;
    const isSelected = btn.dataset.selected === "true";
    const type = outputTypes.find(t => t.name === name);
    if (isSelected) {
      btn.dataset.selected = "false";
      btn.style.background = "var(--ai-option-bg)";
      const iconEl = btn.querySelector(".option-icon");
      if (iconEl && type) iconEl.innerHTML = type.iconSvg;
      if (pillsContainer) {
        const pill = document.getElementById(`pill-${name}`);
        if (pill) pill.remove();
      }
      updateHint(null);
    } else {
      document.querySelectorAll('[data-option-name][data-selected="true"]').forEach(prevBtn => {
        const prevName = prevBtn.dataset.optionName;
        prevBtn.dataset.selected = "false";
        prevBtn.style.background = "var(--ai-option-bg)";
        const prevIconEl = prevBtn.querySelector(".option-icon");
        const prevType = outputTypes.find(t => t.name === prevName);
        if (prevIconEl && prevType) prevIconEl.innerHTML = prevType.iconSvg;
        if (pillsContainer) {
          const prevPill = document.getElementById(`pill-${prevName}`);
          if (prevPill) prevPill.remove();
        }
      });
      btn.dataset.selected = "true";
      btn.style.background = "var(--ai-option-selected-bg)";
      const iconEl = btn.querySelector(".option-icon");
      if (iconEl) iconEl.innerHTML = checkSvg;
      if (pillsContainer && type) {
        const pill = document.createElement("span");
        pill.id = `pill-${name}`;
        pill.style.cssText = "display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 8px 0 8px;border-radius:32px;background:var(--ai-pill-bg);color:var(--ai-pill-text);font-size:14px;white-space:nowrap;cursor:default;";
        pill.innerHTML = `<span style="display:flex;align-items:center"><svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">${type.iconSvg.replace(/<svg[^>]*>/, "").replace("</svg>", "")}</svg></span><span>${name}</span><span class="ai-pill-close" style="display:flex;align-items:center;cursor:pointer;margin-left:2px" data-pill-remove="${name}"><svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M18.3 5.71a1 1 0 0 0-1.42 0L12 10.59 7.12 5.7A1 1 0 0 0 5.7 7.12L10.59 12 5.7 16.88a1 1 0 1 0 1.42 1.42L12 13.41l4.88 4.89a1 1 0 0 0 1.42-1.42L13.41 12l4.89-4.88a1 1 0 0 0 0-1.41Z"/></svg></span>`;
        pill.querySelector(`[data-pill-remove="${name}"]`).addEventListener("click", () => toggleOutputType(name));
        pillsContainer.appendChild(pill);
      }
      updateHint(name);
    }
  };
  const slideCarousel = direction => {
    const track = document.getElementById(trackId);
    if (!track) return;
    const currentPage = parseInt(track.dataset.page || "0", 10);
    const totalPages = Math.ceil(outputTypes.length / ITEMS_PER_PAGE);
    let newPage = currentPage + direction;
    if (newPage < 0) newPage = totalPages - 1;
    if (newPage >= totalPages) newPage = 0;
    track.dataset.page = String(newPage);
    track.style.transform = `translateX(-${newPage * ITEMS_PER_PAGE * ITEM_WIDTH}px)`;
  };
  if (typeof document !== "undefined" && !document.getElementById("agent-carousel-styles")) {
    const style = document.createElement("style");
    style.id = "agent-carousel-styles";
    style.textContent = `
      .agent-carousel-wrap {
        --ai-option-bg: var(--replit-docs-bg-muted, #F1F1EE);
        --ai-option-border: var(--replit-docs-border, #DEDAD5);
        --ai-option-hover-bg: var(--replit-docs-bg-elevated, #F1F1EE);
        --ai-option-selected-bg: var(--replit-docs-bg-elevated, #F1F1EE);
        --ai-text-secondary: var(--replit-docs-text-muted, #5C5C5C);
        --ai-icon-default: var(--replit-docs-text-subtle, #858585);
        --ai-icon-hover: var(--replit-docs-text-muted, #5C5C5C);
      }
      .dark .agent-carousel-wrap,
      html.dark .agent-carousel-wrap,
      [data-theme="dark"] .agent-carousel-wrap {
        --ai-option-bg: var(--replit-docs-bg-elevated, #222223);
        --ai-option-border: var(--replit-docs-border, #39393D);
        --ai-option-hover-bg: var(--replit-docs-bg-muted, #222223);
        --ai-option-selected-bg: var(--replit-docs-bg-muted, #222223);
        --ai-text-secondary: var(--replit-docs-text-muted, #B8B8BE);
        --ai-icon-default: var(--replit-docs-text-subtle, #8E8F97);
        --ai-icon-hover: var(--replit-docs-text-muted, #B8B8BE);
      }
      @keyframes agent-carousel-fade-in {
        from { transform: translateY(10px); opacity: 0; }
        to { transform: translateY(0); opacity: 1; }
      }
      .agent-carousel-wrap .ac-option-btn[data-selected="true"] {
        background: var(--ai-option-selected-bg) !important;
      }
      .agent-carousel-wrap .ac-option-btn[data-correct="true"][data-selected="true"] {
        border-color: #22c55e !important;
        background: rgba(34, 197, 94, 0.08) !important;
      }
      @keyframes ac-hint-fade-in {
        from { opacity: 0; transform: translateY(-4px); }
        to { opacity: 1; transform: translateY(0); }
      }
      .agent-carousel-wrap .ac-hint {
        text-align: center;
        font-size: 13px;
        margin-top: 12px;
        animation: ac-hint-fade-in 200ms ease-out;
      }
      .agent-carousel-wrap .ac-hint-correct {
        color: #22c55e;
      }
      .agent-carousel-wrap .ac-hint-nudge {
        color: var(--ai-text-secondary);
      }
      @media (hover: hover) {
        .agent-carousel-wrap .ac-option-btn:not([data-selected="true"]):hover {
          background: var(--ai-option-hover-bg);
        }
        .agent-carousel-wrap .ac-nav-btn:hover svg {
          color: var(--ai-icon-hover);
        }
      }
      .agent-carousel-wrap {
        overflow: hidden;
        box-sizing: border-box;
      }
    `;
    document.head.appendChild(style);
  }
  const ArrowLeftIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
      <path fillRule="evenodd" d="M4.47 11.47a.75.75 0 0 0 0 1.06l7 7a.75.75 0 1 0 1.06-1.06l-5.72-5.72H19a.75.75 0 0 0 0-1.5H6.81l5.72-5.72a.75.75 0 0 0-1.06-1.06l-7 7Z" clipRule="evenodd" />
    </svg>;
  const ArrowRightIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
      <path fillRule="evenodd" d="M19.53 11.47a.75.75 0 0 1 0 1.06l-7 7a.75.75 0 1 1-1.06-1.06l5.72-5.72H5a.75.75 0 0 1 0-1.5h12.19l-5.72-5.72a.75.75 0 0 1 1.06-1.06l7 7Z" clipRule="evenodd" />
    </svg>;
  const optionIconStyle = {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: "48px",
    height: "48px",
    border: "1px solid var(--ai-option-border)",
    borderRadius: "12px",
    background: "var(--ai-option-bg)",
    cursor: "pointer",
    color: "var(--ai-text-secondary)",
    padding: 0,
    transition: "background 120ms ease-out",
    flexShrink: 0
  };
  return <div className="agent-carousel-wrap" style={{
    fontFamily: "'IBM Plex Sans', sans-serif",
    width: "100%",
    maxWidth: "734px",
    alignSelf: "center",
    margin: "48px auto",
    opacity: 0,
    animation: "agent-carousel-fade-in 300ms ease-out forwards"
  }}>
      <div style={{
    display: "flex",
    justifyContent: "center"
  }}>
        <div style={{
    display: "flex",
    alignItems: "flex-start",
    gap: "16px",
    maxWidth: "100%",
    minWidth: 0
  }}>
          <button className="ac-nav-btn" style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: "24px",
    height: "48px",
    border: "none",
    background: "none",
    cursor: "pointer",
    color: "var(--ai-icon-default)",
    padding: 0,
    flexShrink: 0
  }} aria-label="Previous" type="button" onClick={() => slideCarousel(-1)}>
            {ArrowLeftIcon}
          </button>
          <div style={{
    display: "flex",
    overflow: "hidden",
    width: `${VISIBLE_WIDTH}px`,
    maxWidth: "calc(100vw - 140px)"
  }}>
            <div id={trackId} data-page="0" style={{
    display: "flex",
    transition: "transform 300ms ease-out",
    willChange: "transform"
  }}>
              {outputTypes.map(type => <div key={type.name} style={{
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    gap: "6px",
    width: `${ITEM_WIDTH}px`,
    flexShrink: 0
  }}>
                  <button className="ac-option-btn" data-option-name={type.name} data-correct={correctChoice && type.name === correctChoice ? "true" : undefined} style={optionIconStyle} type="button" onClick={() => toggleOutputType(type.name)}>
                    <span className="option-icon" style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "center"
  }} dangerouslySetInnerHTML={{
    __html: type.iconSvg
  }} />
                  </button>
                  <span style={{
    fontSize: "12px",
    color: "var(--ai-text-secondary)",
    textAlign: "center"
  }}>
                    {type.name}
                  </span>
                </div>)}
            </div>
          </div>
          <button className="ac-nav-btn" style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: "24px",
    height: "48px",
    border: "none",
    background: "none",
    cursor: "pointer",
    color: "var(--ai-icon-default)",
    padding: 0,
    flexShrink: 0
  }} aria-label="Next" type="button" onClick={() => slideCarousel(1)}>
            {ArrowRightIcon}
          </button>
        </div>
      </div>
      {correctChoice && <div id="ac-carousel-hint" style={{
    minHeight: "24px"
  }}></div>}
    </div>;
};

export const AgentInput = ({defaultPrompt = "", highlightPlan = false, highlightStart = false, showTypewriter = true}) => {
  const AGENT_INPUT_TYPEWRITER_SCRIPT_ID = "replit-docs-typewriter-core";
  const AGENT_INPUT_TYPEWRITER_SRC = "https://unpkg.com/typewriter-effect@2.18.2/dist/core.js";
  const AGENT_INPUT_TYPEWRITER_PROMPTS = ["Build a project tracker for my team", "Design a landing page for my coffee shop", "Add Stripe payments to my app"];
  const AGENT_INPUT_TYPING_SPEED = 40;
  const AGENT_INPUT_DELETE_SPEED = 20;
  const AGENT_INPUT_PAUSE_AFTER = 2000;
  const AGENT_INPUT_START_DELAY = 500;
  const getAgentInputTypewriterLoader = () => {
    if (typeof window === "undefined") {
      return null;
    }
    if (!window.__replitDocsAgentInputTypewriterLoader) {
      window.__replitDocsAgentInputTypewriterLoader = {};
    }
    return window.__replitDocsAgentInputTypewriterLoader;
  };
  const ensureAgentInputTypewriterCore = () => {
    if (typeof window === "undefined" || typeof document === "undefined") {
      return Promise.resolve(null);
    }
    if (window.Typewriter) {
      return Promise.resolve(window.Typewriter);
    }
    const loader = getAgentInputTypewriterLoader();
    if (loader.promise) {
      return loader.promise;
    }
    loader.promise = new Promise((resolve, reject) => {
      const handleLoad = () => {
        if (window.Typewriter) {
          resolve(window.Typewriter);
          return;
        }
        loader.promise = null;
        reject(new Error("Typewriter core loaded without a global Typewriter export."));
      };
      const handleError = () => {
        loader.promise = null;
        reject(new Error("Failed to load typewriter core."));
      };
      const existingScript = document.getElementById(AGENT_INPUT_TYPEWRITER_SCRIPT_ID);
      if (existingScript) {
        existingScript.addEventListener("load", handleLoad, {
          once: true
        });
        existingScript.addEventListener("error", handleError, {
          once: true
        });
        return;
      }
      const script = document.createElement("script");
      script.id = AGENT_INPUT_TYPEWRITER_SCRIPT_ID;
      script.src = AGENT_INPUT_TYPEWRITER_SRC;
      script.async = true;
      script.addEventListener("load", handleLoad, {
        once: true
      });
      script.addEventListener("error", handleError, {
        once: true
      });
      document.head.appendChild(script);
    });
    return loader.promise;
  };
  const getAgentInputTypewriterRegistry = () => {
    if (typeof window === "undefined") {
      return null;
    }
    if (!window.__replitDocsAgentInputTypewriters) {
      window.__replitDocsAgentInputTypewriters = new WeakMap();
    }
    return window.__replitDocsAgentInputTypewriters;
  };
  const findAgentInputContainer = node => node?.closest?.("[data-agent-input-container]") || null;
  const getAgentInputElements = container => ({
    textarea: container?.querySelector?.('[data-agent-input-role="textarea"]') || null,
    startButton: container?.querySelector?.('[data-agent-input-role="start-button"]') || null,
    pillsContainer: container?.querySelector?.('[data-agent-input-role="pills"]') || null
  });
  const getAgentInputPromptValue = container => {
    const {textarea} = getAgentInputElements(container);
    return textarea?.value?.trim() || "";
  };
  const updateAgentInputButtonState = container => {
    const {startButton} = getAgentInputElements(container);
    if (!startButton) {
      return;
    }
    const hasText = getAgentInputPromptValue(container).length > 0;
    startButton.style.opacity = hasText ? "1" : "0.4";
    startButton.style.cursor = hasText ? "pointer" : "not-allowed";
  };
  const stopAgentInputTypewriter = (textarea, {placeholder, clearDemo = false} = {}) => {
    if (typeof window === "undefined" || !textarea) {
      return;
    }
    const registry = getAgentInputTypewriterRegistry();
    const record = registry?.get(textarea);
    if (!record) {
      if (placeholder) {
        textarea.setAttribute("placeholder", placeholder);
      }
      return;
    }
    record.stopped = true;
    if (record.startTimer) {
      window.clearTimeout(record.startTimer);
    }
    if (record.writeFrame) {
      window.cancelAnimationFrame(record.writeFrame);
    }
    if (record.typewriter?.stop) {
      record.typewriter.stop();
    }
    textarea.removeEventListener("focus", record.handleFocus);
    textarea.removeEventListener("pointerdown", record.handlePointerDown);
    textarea.removeEventListener("input", record.handleInput);
    if (clearDemo && textarea.value === record.pendingValue) {
      textarea.value = "";
    }
    textarea.setAttribute("placeholder", placeholder || "");
    updateAgentInputButtonState(record.container);
    registry.delete(textarea);
  };
  const startAgentInputTypewriter = (container, {defaultPrompt, placeholder, showTypewriter}) => {
    if (typeof window === "undefined" || typeof document === "undefined" || !container) {
      return;
    }
    const {textarea} = getAgentInputElements(container);
    if (!textarea) {
      return;
    }
    if (!showTypewriter || defaultPrompt) {
      stopAgentInputTypewriter(textarea, {
        placeholder
      });
      textarea.setAttribute("placeholder", placeholder);
      updateAgentInputButtonState(container);
      return;
    }
    const registry = getAgentInputTypewriterRegistry();
    const existingRecord = registry.get(textarea);
    if (existingRecord && !existingRecord.stopped) {
      updateAgentInputButtonState(container);
      return;
    }
    textarea.setAttribute("placeholder", "");
    if (textarea.value) {
      textarea.value = "";
    }
    updateAgentInputButtonState(container);
    const record = {
      container,
      element: textarea,
      pendingValue: "",
      renderedValue: "",
      stopped: false,
      startTimer: null,
      writeFrame: null,
      typewriter: null,
      handleFocus: null,
      handlePointerDown: null,
      handleInput: null
    };
    const queueValue = nextValue => {
      record.pendingValue = nextValue;
      if (record.writeFrame) {
        return;
      }
      record.writeFrame = window.requestAnimationFrame(() => {
        record.writeFrame = null;
        if (record.stopped || registry.get(textarea) !== record || !textarea.isConnected) {
          return;
        }
        if (textarea.value !== record.pendingValue) {
          textarea.value = record.pendingValue;
        }
        updateAgentInputButtonState(container);
      });
    };
    const stopDemo = () => {
      stopAgentInputTypewriter(textarea, {
        placeholder,
        clearDemo: true
      });
    };
    record.handleFocus = stopDemo;
    record.handlePointerDown = stopDemo;
    record.handleInput = stopDemo;
    registry.set(textarea, record);
    textarea.addEventListener("focus", record.handleFocus, {
      once: true
    });
    textarea.addEventListener("pointerdown", record.handlePointerDown, {
      once: true
    });
    textarea.addEventListener("input", record.handleInput, {
      once: true
    });
    record.startTimer = window.setTimeout(() => {
      ensureAgentInputTypewriterCore().then(Typewriter => {
        if (!Typewriter || record.stopped || registry.get(textarea) !== record || !textarea.isConnected) {
          return;
        }
        const typewriter = new Typewriter(null, {
          loop: true,
          delay: AGENT_INPUT_TYPING_SPEED,
          deleteSpeed: AGENT_INPUT_DELETE_SPEED,
          cursor: "",
          skipAddStyles: true,
          wrapperClassName: "",
          cursorClassName: "",
          onCreateTextNode: character => {
            record.renderedValue += character;
            queueValue(record.renderedValue);
            return null;
          },
          onRemoveNode: () => {
            record.renderedValue = record.renderedValue.slice(0, -1);
            queueValue(record.renderedValue);
          }
        });
        AGENT_INPUT_TYPEWRITER_PROMPTS.forEach(prompt => {
          typewriter.typeString(prompt).pauseFor(AGENT_INPUT_PAUSE_AFTER).deleteAll(AGENT_INPUT_DELETE_SPEED).pauseFor(400);
        });
        record.typewriter = typewriter;
        typewriter.start();
      }).catch(() => {
        stopAgentInputTypewriter(textarea, {
          placeholder
        });
      });
    }, AGENT_INPUT_START_DELAY);
  };
  if (typeof document !== "undefined" && !window.LZString) {
    const script = document.createElement("script");
    script.src = "https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.5.0/lz-string.min.js";
    document.head.appendChild(script);
  }
  const placeholder = "Describe your idea, Replit will bring it to life...";
  const outputTypes = [{
    name: "Web",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M12 1.25c5.937 0 10.75 4.813 10.75 10.75S17.937 22.75 12 22.75 1.25 17.937 1.25 12 6.063 1.25 12 1.25Zm-9.217 11.5a9.25 9.25 0 0 0 7.468 8.333 15.25 15.25 0 0 1-2.982-8.333H2.783Zm13.948 0a15.249 15.249 0 0 1-2.983 8.333 9.25 9.25 0 0 0 7.469-8.333H16.73Zm-7.958 0A13.748 13.748 0 0 0 12 20.876a13.748 13.748 0 0 0 3.227-8.126H8.773Zm1.478-9.834a9.251 9.251 0 0 0-7.468 8.334H7.27a15.251 15.251 0 0 1 2.982-8.334ZM12 3.123a13.747 13.747 0 0 0-3.227 8.127h6.454A13.748 13.748 0 0 0 12 3.123Zm1.748-.207a15.25 15.25 0 0 1 2.983 8.334h4.486a9.251 9.251 0 0 0-7.469-8.334Z" clip-rule="evenodd" /></svg>',
    icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
          <path fillRule="evenodd" d="M12 1.25c5.937 0 10.75 4.813 10.75 10.75S17.937 22.75 12 22.75 1.25 17.937 1.25 12 6.063 1.25 12 1.25Zm-9.217 11.5a9.25 9.25 0 0 0 7.468 8.333 15.25 15.25 0 0 1-2.982-8.333H2.783Zm13.948 0a15.249 15.249 0 0 1-2.983 8.333 9.25 9.25 0 0 0 7.469-8.333H16.73Zm-7.958 0A13.748 13.748 0 0 0 12 20.876a13.748 13.748 0 0 0 3.227-8.126H8.773Zm1.478-9.834a9.251 9.251 0 0 0-7.468 8.334H7.27a15.251 15.251 0 0 1 2.982-8.334ZM12 3.123a13.747 13.747 0 0 0-3.227 8.127h6.454A13.748 13.748 0 0 0 12 3.123Zm1.748-.207a15.25 15.25 0 0 1 2.983 8.334h4.486a9.251 9.251 0 0 0-7.469-8.334Z" clipRule="evenodd" />
        </svg>
  }, {
    name: "Mobile",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M7 2.75c-.69 0-1.25.56-1.25 1.25v16c0 .69.56 1.25 1.25 1.25h10c.69 0 1.25-.56 1.25-1.25V4c0-.69-.56-1.25-1.25-1.25H7ZM4.25 4A2.75 2.75 0 0 1 7 1.25h10A2.75 2.75 0 0 1 19.75 4v16A2.75 2.75 0 0 1 17 22.75H7A2.75 2.75 0 0 1 4.25 20V4Zm7 14a.75.75 0 0 1 .75-.75h.01a.75.75 0 0 1 0 1.5H12a.75.75 0 0 1-.75-.75Z" clip-rule="evenodd" /></svg>',
    icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
          <path fillRule="evenodd" d="M7 2.75c-.69 0-1.25.56-1.25 1.25v16c0 .69.56 1.25 1.25 1.25h10c.69 0 1.25-.56 1.25-1.25V4c0-.69-.56-1.25-1.25-1.25H7ZM4.25 4A2.75 2.75 0 0 1 7 1.25h10A2.75 2.75 0 0 1 19.75 4v16A2.75 2.75 0 0 1 17 22.75H7A2.75 2.75 0 0 1 4.25 20V4Zm7 14a.75.75 0 0 1 .75-.75h.01a.75.75 0 0 1 0 1.5H12a.75.75 0 0 1-.75-.75Z" clipRule="evenodd" />
        </svg>
  }, {
    name: "Slides",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M20 2.25A2.75 2.75 0 0 1 22.75 5v14A2.75 2.75 0 0 1 20 21.75h-8A2.75 2.75 0 0 1 9.25 19V5A2.75 2.75 0 0 1 12 2.25h8Zm-8 1.5c-.69 0-1.25.56-1.25 1.25v14c0 .69.56 1.25 1.25 1.25h8c.69 0 1.25-.56 1.25-1.25V5c0-.69-.56-1.25-1.25-1.25h-8Z" clip-rule="evenodd" /><path d="M6 4.25a.75.75 0 0 1 .75.75v14a.75.75 0 0 1-1.5 0V5A.75.75 0 0 1 6 4.25ZM2 6.25a.75.75 0 0 1 .75.75v10a.75.75 0 0 1-1.5 0V7A.75.75 0 0 1 2 6.25Z" /></svg>',
    icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
          <path fillRule="evenodd" d="M20 2.25A2.75 2.75 0 0 1 22.75 5v14A2.75 2.75 0 0 1 20 21.75h-8A2.75 2.75 0 0 1 9.25 19V5A2.75 2.75 0 0 1 12 2.25h8Zm-8 1.5c-.69 0-1.25.56-1.25 1.25v14c0 .69.56 1.25 1.25 1.25h8c.69 0 1.25-.56 1.25-1.25V5c0-.69-.56-1.25-1.25-1.25h-8Z" clipRule="evenodd" />
          <path d="M6 4.25a.75.75 0 0 1 .75.75v14a.75.75 0 0 1-1.5 0V5A.75.75 0 0 1 6 4.25ZM2 6.25a.75.75 0 0 1 .75.75v10a.75.75 0 0 1-1.5 0V7A.75.75 0 0 1 2 6.25Z" />
        </svg>
  }, {
    name: "Animation",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M10.024 7.25c.31.004.613.091.878.251l4.996 2.996a1.752 1.752 0 0 1 .625 2.367 1.75 1.75 0 0 1-.625.639v-.001l-4.995 2.995.001.001a1.75 1.75 0 0 1-2.654-1.505v-5.99a1.75 1.75 0 0 1 1.774-1.753Zm-.02 1.5a.252.252 0 0 0-.22.124.253.253 0 0 0-.034.127v5.998a.252.252 0 0 0 .127.219.253.253 0 0 0 .252-.004l.002-.001 4.997-2.997.002-.001a.252.252 0 0 0 .122-.215.25.25 0 0 0-.122-.215h-.002L10.13 8.786h-.002a.25.25 0 0 0-.125-.037Z" clip-rule="evenodd" /><path fill-rule="evenodd" d="M12 1.25c5.937 0 10.75 4.813 10.75 10.75S17.937 22.75 12 22.75 1.25 17.937 1.25 12 6.063 1.25 12 1.25Zm0 1.5a9.25 9.25 0 1 0 0 18.5 9.25 9.25 0 0 0 0-18.5Z" clip-rule="evenodd" /></svg>',
    icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
          <path fillRule="evenodd" d="M10.024 7.25c.31.004.613.091.878.251l4.996 2.996a1.752 1.752 0 0 1 .625 2.367 1.75 1.75 0 0 1-.625.639v-.001l-4.995 2.995.001.001a1.75 1.75 0 0 1-2.654-1.505v-5.99a1.75 1.75 0 0 1 1.774-1.753Zm-.02 1.5a.252.252 0 0 0-.22.124.253.253 0 0 0-.034.127v5.998a.252.252 0 0 0 .127.219.253.253 0 0 0 .252-.004l.002-.001 4.997-2.997.002-.001a.252.252 0 0 0 .122-.215.25.25 0 0 0-.122-.215h-.002L10.13 8.786h-.002a.25.25 0 0 0-.125-.037Z" clipRule="evenodd" />
          <path fillRule="evenodd" d="M12 1.25c5.937 0 10.75 4.813 10.75 10.75S17.937 22.75 12 22.75 1.25 17.937 1.25 12 6.063 1.25 12 1.25Zm0 1.5a9.25 9.25 0 1 0 0 18.5 9.25 9.25 0 0 0 0-18.5Z" clipRule="evenodd" />
        </svg>
  }, {
    name: "Design",
    iconSvg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M6.5 11.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM17.5 9.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM8.5 6.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM13.5 5.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5Z" /><path fill-rule="evenodd" d="M12 1.25c2.827 0 5.553 1.01 7.573 2.828C21.596 5.9 22.75 8.388 22.75 11A5.749 5.749 0 0 1 17 16.75h-2.25a1 1 0 0 0-.8 1.6l.3.4.1.143a2.5 2.5 0 0 1-2.1 3.857H12a10.75 10.75 0 1 1 0-21.5Zm0 1.5a9.25 9.25 0 1 0 0 18.5h.25a1 1 0 0 0 .8-1.6l-.3-.4a2.5 2.5 0 0 1 2-4H17l.21-.005A4.25 4.25 0 0 0 21.25 11c0-2.161-.953-4.252-2.68-5.807C16.84 3.636 14.476 2.75 12 2.75Z" clip-rule="evenodd" /></svg>',
    icon: <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
          <path d="M6.5 11.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM17.5 9.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM8.5 6.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM13.5 5.25a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5Z" />
          <path fillRule="evenodd" d="M12 1.25c2.827 0 5.553 1.01 7.573 2.828C21.596 5.9 22.75 8.388 22.75 11A5.749 5.749 0 0 1 17 16.75h-2.25a1 1 0 0 0-.8 1.6l.3.4.1.143a2.5 2.5 0 0 1-2.1 3.857H12a10.75 10.75 0 1 1 0-21.5Zm0 1.5a9.25 9.25 0 1 0 0 18.5h.25a1 1 0 0 0 .8-1.6l-.3-.4a2.5 2.5 0 0 1 2-4H17l.21-.005A4.25 4.25 0 0 0 21.25 11c0-2.161-.953-4.252-2.68-5.807C16.84 3.636 14.476 2.75 12 2.75Z" clipRule="evenodd" />
        </svg>
  }];
  const checkSvg = '<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M20.53 5.47a.75.75 0 0 1 0 1.06l-11 11a.75.75 0 0 1-1.06 0l-5-5a.75.75 0 1 1 1.06-1.06L9 15.94 19.47 5.47a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" /></svg>';
  if (typeof document !== "undefined" && !document.getElementById("agent-input-styles")) {
    const style = document.createElement("style");
    style.id = "agent-input-styles";
    style.textContent = `
      /* Theme variables - light mode */
      [data-agent-input-container] {
        --ai-surface-bg: var(--replit-docs-bg, #F6F6F4);
        --ai-surface-higher: var(--replit-docs-bg-elevated, #F1F1EE);
        --ai-border-default: var(--replit-docs-border, #DEDAD5);
        --ai-border-strong: var(--replit-docs-border-strong, #CAC4BE);
        --ai-text-secondary: var(--replit-docs-text-muted, #5C5C5C);
        --ai-text-tertiary: var(--replit-docs-text-subtle, #858585);
        --ai-text-primary: var(--replit-docs-text, #1D1D1D);
        --ai-button-bg: var(--replit-docs-bg-muted, #F1F1EE);
        --ai-button-bg-hover: var(--replit-docs-bg-elevated, #F1F1EE);
        --ai-icon-default: var(--replit-docs-text-subtle, #858585);
        --ai-icon-hover: var(--replit-docs-text-muted, #5C5C5C);
        --ai-shadow: 0 2px 6px #00000005;
        --ai-option-bg: var(--replit-docs-bg-elevated, #F1F1EE);
        --ai-option-border: var(--replit-docs-border, #DEDAD5);
        --ai-option-hover-bg: var(--replit-docs-bg-muted, #F1F1EE);
        --ai-option-selected-bg: var(--replit-docs-bg-muted, #F1F1EE);
        --ai-pill-bg: #CDDCF1;
        --ai-pill-text: var(--replit-docs-text-muted, #5C5C5C);
      }

      /* Theme variables - dark mode */
      .dark [data-agent-input-container],
      html.dark [data-agent-input-container],
      [data-theme="dark"] [data-agent-input-container] {
        --ai-surface-bg: var(--replit-docs-bg, #1E1E1F);
        --ai-surface-higher: var(--replit-docs-bg-elevated, #222223);
        --ai-border-default: var(--replit-docs-border, #39393D);
        --ai-border-strong: var(--replit-docs-border-strong, #4A4A50);
        --ai-text-secondary: var(--replit-docs-text-muted, #B8B8BE);
        --ai-text-tertiary: var(--replit-docs-text-subtle, #8E8F97);
        --ai-text-primary: var(--replit-docs-text, #F5F5F5);
        --ai-button-bg: var(--replit-docs-bg-elevated, #222223);
        --ai-button-bg-hover: var(--replit-docs-bg-muted, #222223);
        --ai-icon-default: var(--replit-docs-text-subtle, #8E8F97);
        --ai-icon-hover: var(--replit-docs-text-muted, #B8B8BE);
        --ai-shadow: 0 2px 6px #00000020;
        --ai-option-bg: var(--replit-docs-bg-elevated, #222223);
        --ai-option-border: var(--replit-docs-border, #39393D);
        --ai-option-hover-bg: var(--replit-docs-bg-muted, #222223);
        --ai-option-selected-bg: var(--replit-docs-bg-muted, #222223);
        --ai-pill-bg: #2A3A4D;
        --ai-pill-text: #D0D8E4;
      }

      .agent-input-container {
        box-sizing: border-box;
      }

      /* Entry animation */
      @keyframes agent-input-fade-in-up {
        from { transform: translateY(10px); opacity: 0; }
        to { transform: translateY(0); opacity: 1; }
      }

      /* Hover state for input box */
      [data-agent-input-container]:has([data-agent-input-role="inner"]:hover) [data-agent-input-role="inner"] {
        border-color: #85C7FF !important;
      }

      /* Focus state for input box */
      [data-agent-input-container]:has([data-agent-input-role="inner"]:focus-within) [data-agent-input-role="inner"] {
        border-color: #0079F2 !important;
      }

      /* Icon button hover */
      @media (hover: hover) {
        [data-agent-input-container] .ai-icon-btn:hover {
          background: var(--ai-button-bg-hover);
        }
        [data-agent-input-container] .ai-icon-btn:hover svg {
          color: var(--ai-icon-hover);
        }
        [data-agent-input-container] .ai-option-btn:not([data-selected="true"]):hover {
          background: var(--ai-option-hover-bg);
        }
        [data-agent-input-container] .ai-plan-btn:hover {
          background: var(--ai-button-bg-hover);
        }
        [data-agent-input-container] .ai-nav-btn:hover svg {
          color: var(--ai-icon-hover);
        }
        [data-agent-input-container] .ai-pill-close:hover {
          opacity: 0.7;
        }
      }
      @keyframes plan-border-spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
      }
      [data-agent-input-container] .ai-plan-wrap {
        position: relative;
        border-radius: 32px;
        padding: 2px;
        overflow: hidden;
      }
      [data-agent-input-container] .ai-plan-wrap::before {
        content: '';
        position: absolute;
        inset: -50%;
        background: conic-gradient(
          #3b82f6, #8b5cf6, #ec4899, #f59e0b, #10b981, #3b82f6
        );
        animation: plan-border-spin 1s linear infinite;
      }
      [data-agent-input-container] .ai-plan-wrap .ai-plan-btn-highlight {
        position: relative;
        background: var(--ai-surface-higher);
        color: var(--ai-text-primary);
        font-weight: 400;
        border: none;
        border-radius: 32px;
        z-index: 1;
      }
      [data-agent-input-container] .ai-plan-wrap.ai-plan-off::before {
        animation: none;
        background: transparent;
      }
      [data-agent-input-container] .ai-plan-wrap.ai-plan-off .ai-plan-btn-highlight {
        background: var(--ai-button-bg);
        color: var(--ai-text-secondary);
      }
      /* Plan checkbox styles */
      [data-agent-input-container] .ai-plan-checkbox-label {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        height: 32px;
        padding: 0 8px;
        border-radius: var(--border-radius-6, 6px);
        background: var(--ai-button-bg);
        cursor: pointer;
        font-size: 12px;
        font-family: inherit;
        color: var(--ai-text-secondary);
        transition: background 120ms ease-out;
        user-select: none;
      }
      @media (hover: hover) {
        [data-agent-input-container] .ai-plan-checkbox-label:hover {
          background: var(--ai-button-bg-hover);
        }
      }
      [data-agent-input-container] .ai-plan-checkbox-input {
        width: 20px;
        height: 20px;
        margin: 0;
        accent-color: #0079F2;
        cursor: pointer;
      }
      [data-agent-input-container] .ai-start-wrap {
        position: relative;
        display: inline-flex;
        padding: 3px;
        border-radius: 8px;
        overflow: hidden;
      }
      [data-agent-input-container] .ai-start-wrap::before {
        content: '';
        position: absolute;
        inset: -50%;
        background: conic-gradient(
          #3b82f6, #8b5cf6, #ec4899, #f59e0b, #10b981, #3b82f6
        );
        animation: plan-border-spin 1s linear infinite;
      }
      [data-agent-input-container] .ai-start-wrap .ai-start-btn-highlight {
        position: relative;
        background: var(--ai-surface-higher);
        border: none;
        border-radius: 6px;
        z-index: 1;
      }
    `;
    document.head.appendChild(style);
  }
  const getLink = (container, promptOverride) => {
    if (typeof document === "undefined" || !window.LZString) return "";
    const prompt = promptOverride || getAgentInputPromptValue(container);
    if (!prompt) return "";
    const encoded = window.LZString.compressToEncodedURIComponent(prompt);
    const utm = "utm_source=replit-docs&utm_medium=docs&utm_campaign=docs-intro-agent-input&utm_content=homepage-prompt-box";
    return `https://replit.com/?prompt=${encoded}&referrer=replit-docs&${utm}`;
  };
  const handleStartClick = e => {
    e.preventDefault();
    const container = findAgentInputContainer(e.currentTarget);
    const link = getLink(container);
    if (link) window.open(link, "_blank");
  };
  const toggleOutputType = name => {
    const btn = document.querySelector(`[data-option-name="${name}"]`);
    const pillsContainer = document.getElementById("agent-input-pills");
    if (!btn || !pillsContainer) return;
    const isSelected = btn.dataset.selected === "true";
    if (isSelected) {
      btn.dataset.selected = "false";
      btn.style.background = "var(--ai-option-bg)";
      const iconEl = btn.querySelector(".option-icon");
      const type = outputTypes.find(t => t.name === name);
      if (iconEl && type) iconEl.innerHTML = type.iconSvg;
      const pill = document.getElementById(`pill-${name}`);
      if (pill) pill.remove();
    } else {
      document.querySelectorAll('[data-option-name][data-selected="true"]').forEach(prevBtn => {
        const prevName = prevBtn.dataset.optionName;
        prevBtn.dataset.selected = "false";
        prevBtn.style.background = "var(--ai-option-bg)";
        const prevIconEl = prevBtn.querySelector(".option-icon");
        const prevType = outputTypes.find(t => t.name === prevName);
        if (prevIconEl && prevType) prevIconEl.innerHTML = prevType.iconSvg;
        const prevPill = document.getElementById(`pill-${prevName}`);
        if (prevPill) prevPill.remove();
      });
      btn.dataset.selected = "true";
      btn.style.background = "var(--ai-option-selected-bg)";
      const iconEl = btn.querySelector(".option-icon");
      if (iconEl) iconEl.innerHTML = checkSvg;
      const type = outputTypes.find(t => t.name === name);
      if (type) {
        const pill = document.createElement("span");
        pill.id = `pill-${name}`;
        pill.style.cssText = "display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 8px 0 8px;border-radius:32px;background:var(--ai-pill-bg);color:var(--ai-pill-text);font-size:14px;white-space:nowrap;cursor:default;";
        pill.innerHTML = `<span style="display:flex;align-items:center"><svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">${type.iconSvg.replace(/<svg[^>]*>/, "").replace("</svg>", "")}</svg></span><span>${name}</span><span class="ai-pill-close" style="display:flex;align-items:center;cursor:pointer;margin-left:2px" data-pill-remove="${name}"><svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M18.3 5.71a1 1 0 0 0-1.42 0L12 10.59 7.12 5.7A1 1 0 0 0 5.7 7.12L10.59 12 5.7 16.88a1 1 0 1 0 1.42 1.42L12 13.41l4.88 4.89a1 1 0 0 0 1.42-1.42L13.41 12l4.89-4.88a1 1 0 0 0 0-1.41Z"/></svg></span>`;
        pill.querySelector(`[data-pill-remove="${name}"]`).addEventListener("click", () => toggleOutputType(name));
        pillsContainer.appendChild(pill);
      }
    }
  };
  const PlusIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
      <path d="M12 4.25a.75.75 0 0 1 .75.75v6.25H19a.75.75 0 0 1 0 1.5h-6.25V19a.75.75 0 0 1-1.5 0v-6.25H5a.75.75 0 0 1 0-1.5h6.25V5a.75.75 0 0 1 .75-.75Z" />
    </svg>;
  const MicIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
      <path d="M19 9.25a.75.75 0 0 1 .75.75v2a7.75 7.75 0 0 1-7 7.713V22a.75.75 0 0 1-1.5 0v-2.287a7.75 7.75 0 0 1-6.99-7.328L4.25 12v-2a.75.75 0 0 1 1.5 0v2l.008.31A6.25 6.25 0 0 0 12 18.25l.31-.008a6.249 6.249 0 0 0 5.932-5.932l.008-.31v-2a.75.75 0 0 1 .75-.75Z" />
      <path fillRule="evenodd" d="M12 1.25A3.75 3.75 0 0 1 15.75 5v7a3.75 3.75 0 1 1-7.5 0V5A3.75 3.75 0 0 1 12 1.25Zm0 1.5A2.25 2.25 0 0 0 9.75 5v7a2.25 2.25 0 0 0 4.5 0V5A2.25 2.25 0 0 0 12 2.75Z" clipRule="evenodd" />
    </svg>;
  const ArrowUpIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
      <path fillRule="evenodd" d="M11.47 4.47a.75.75 0 0 1 1.06 0l7 7a.75.75 0 1 1-1.06 1.06l-5.72-5.72V19a.75.75 0 0 1-1.5 0V6.81l-5.72 5.72a.75.75 0 0 1-1.06-1.06l7-7Z" clipRule="evenodd" />
    </svg>;
  const ArrowLeftIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
      <path fillRule="evenodd" d="M4.47 11.47a.75.75 0 0 0 0 1.06l7 7a.75.75 0 1 0 1.06-1.06l-5.72-5.72H19a.75.75 0 0 0 0-1.5H6.81l5.72-5.72a.75.75 0 0 0-1.06-1.06l-7 7Z" clipRule="evenodd" />
    </svg>;
  const ArrowRightIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
      <path fillRule="evenodd" d="M19.53 11.47a.75.75 0 0 1 0 1.06l-7 7a.75.75 0 1 1-1.06-1.06l5.72-5.72H5a.75.75 0 0 1 0-1.5h12.19l-5.72-5.72a.75.75 0 0 1 1.06-1.06l7 7Z" clipRule="evenodd" />
    </svg>;
  const iconBtnStyle = {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: "28px",
    height: "28px",
    border: "none",
    borderRadius: "6px",
    background: "transparent",
    cursor: "pointer",
    color: "var(--ai-icon-default)",
    padding: 0,
    transition: "background 120ms ease-out"
  };
  const optionIconStyle = {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: "48px",
    height: "48px",
    border: "1px solid var(--ai-option-border)",
    borderRadius: "12px",
    background: "var(--ai-option-bg)",
    cursor: "pointer",
    color: "var(--ai-text-secondary)",
    padding: 0,
    transition: "background 120ms ease-out",
    flexShrink: 0
  };
  const initAgentInput = container => {
    if (!container) {
      return;
    }
    updateAgentInputButtonState(container);
    startAgentInputTypewriter(container, {
      defaultPrompt,
      placeholder,
      showTypewriter
    });
    const ta = container.querySelector('[data-agent-input-role="textarea"]');
    if (ta && ta.value) {
      requestAnimationFrame(() => {
        ta.style.height = "auto";
        ta.style.height = ta.scrollHeight + "px";
      });
    }
  };
  return <div ref={initAgentInput} data-agent-input-container className="agent-input-container" style={{
    fontFamily: "'IBM Plex Sans', sans-serif",
    width: "100%",
    maxWidth: "734px",
    alignSelf: "center",
    margin: "48px auto",
    opacity: 0,
    animation: "agent-input-fade-in-up 300ms ease-out forwards"
  }}>
      <div style={{
    display: "flex",
    flexDirection: "column",
    gap: "24px"
  }}>
        {}
        <div data-agent-input-role="inner" style={{
    position: "relative",
    borderRadius: "6px",
    border: "1px solid var(--ai-border-strong)",
    background: "var(--ai-surface-bg)",
    transition: "border-color 120ms ease-out",
    boxShadow: "var(--ai-shadow)"
  }}>
          {}
          <div style={{
    padding: "12px 12px 48px 12px"
  }}>
            <textarea data-agent-input-role="textarea" placeholder={placeholder} defaultValue={defaultPrompt} rows={1} onInput={e => {
    const ta = e.currentTarget;
    ta.style.height = "auto";
    ta.style.height = ta.scrollHeight + "px";
    updateAgentInputButtonState(findAgentInputContainer(ta));
  }} style={{
    display: "block",
    width: "100%",
    minHeight: "21px",
    maxHeight: "calc(14px * 1.5 * 10)",
    padding: 0,
    margin: 0,
    border: "none",
    outline: "none",
    resize: "none",
    fontSize: "14px",
    lineHeight: "1.5",
    color: "var(--ai-text-primary)",
    background: "transparent",
    fontFamily: "inherit",
    boxSizing: "border-box",
    overflowY: "auto"
  }} />
          </div>
          {}
          <div style={{
    position: "absolute",
    left: "8px",
    right: "8px",
    bottom: "8px",
    display: "flex",
    justifyContent: "space-between",
    alignItems: "center"
  }}>
            {}
            <div style={{
    display: "flex",
    alignItems: "center",
    gap: "8px",
    overflow: "hidden",
    minWidth: 0
  }}>
              <button className="ai-icon-btn" style={iconBtnStyle} aria-label="Add attachment" type="button">
                {PlusIcon}
              </button>
              <div id="agent-input-pills" data-agent-input-role="pills" style={{
    display: "flex",
    alignItems: "center",
    gap: "6px",
    overflow: "hidden"
  }}></div>
            </div>
            {}
            <div style={{
    display: "flex",
    alignItems: "center",
    gap: "8px",
    flexShrink: 0
  }}>
              {highlightPlan ? <div className="ai-plan-wrap" onClick={e => {
    const wrap = e.currentTarget;
    wrap.classList.toggle("ai-plan-off");
  }}>
                  <label className="ai-plan-btn-highlight" style={{
    display: "flex",
    alignItems: "center",
    gap: "6px",
    height: "32px",
    padding: "0 8px",
    cursor: "pointer",
    fontSize: "12px",
    fontFamily: "inherit",
    transition: "background 120ms ease-out"
  }}>
                    <input className="ai-plan-checkbox-input" type="checkbox" aria-label="Plan mode" name="Plan mode" defaultChecked />
                    <span>Plan</span>
                  </label>
                </div> : <label className="ai-plan-checkbox-label">
                  <input className="ai-plan-checkbox-input" type="checkbox" aria-label="Plan mode" name="Plan mode" />
                  <span>Plan</span>
                </label>}
              <button className="ai-icon-btn" style={iconBtnStyle} aria-label="Start voice input" type="button">
                {MicIcon}
              </button>
              {highlightStart ? <div className="ai-start-wrap">
                  <button data-agent-input-role="start-button" className="ai-icon-btn ai-start-btn-highlight" onClick={handleStartClick} type="button" aria-label="Start" style={{
    ...iconBtnStyle,
    borderRadius: "6px",
    background: "#0079F2",
    color: "#fff",
    opacity: defaultPrompt ? "1" : "0.4",
    cursor: defaultPrompt ? "pointer" : "not-allowed"
  }}>
                    {ArrowUpIcon}
                  </button>
                </div> : <button data-agent-input-role="start-button" className="ai-icon-btn" onClick={handleStartClick} type="button" aria-label="Start" style={{
    ...iconBtnStyle,
    background: "#0079F2",
    color: "#fff",
    opacity: defaultPrompt ? "1" : "0.4",
    cursor: defaultPrompt ? "pointer" : "not-allowed"
  }}>
                  {ArrowUpIcon}
                </button>}
            </div>
          </div>
        </div>
      </div>
    </div>;
};

<WistiaEmbed videoId="8ndyranc1n" title="Replit Canvas overview" />

## What is the Canvas?

The Canvas is a space to explore and iterate on designs with Agent. Here, you'll see your artifacts — such as apps, videos, and slides — displayed in a frame. You can work with Agent to create mockups, compare design directions, and apply changes back to your app — all from one visual board.

<Frame>
  <img src="https://mintcdn.com/replit/H-TDTs94BJ7lxH24/images/replitai/canvas-desktop.png?fit=max&auto=format&n=H-TDTs94BJ7lxH24&q=85&s=0df55dbeffbe8039069e990fbd3ffc07" alt="Canvas showing an app preview alongside Agent chat with task updates" width="3452" height="2006" data-path="images/replitai/canvas-desktop.png" />
</Frame>

## What's on the Canvas

The Canvas is an infinite board where you can see and work with everything visually.

<Frame>
  <img src="https://mintcdn.com/replit/oJ1dYuTDBrvuslEj/images/replitai/canvas-mockups.png?fit=max&auto=format&n=oJ1dYuTDBrvuslEj&q=85&s=ef0f0cbde2c8685772a84dc07c10ac24" alt="Canvas showing multiple design mockups laid out side by side — dark theme, mobile views, and detail pages" width="3452" height="1620" data-path="images/replitai/canvas-mockups.png" />
</Frame>

* **Your apps**: Your running apps appear as live, interactive previews right on the Canvas. You can click around and use them just like you would in a browser.
* **Design mockups**: Visual prototypes Agent creates for you. These look and feel like real pages — you can interact with them, resize them, and ask Agent to tweak them — but they're separate from your live app so you can experiment freely.
* **Shapes and drawings**: Rectangles, circles, stars, arrows, hearts, and more. Use these to sketch rough ideas, mark up designs, or map out how screens connect.
* **Text and sticky notes**: Add labels or notes anywhere on the Canvas to organize your thoughts.
* **Images**: Drop screenshots or reference images onto the Canvas. Agent can recreate or riff on what it sees.
* **Videos**: Place video files on the Canvas alongside your other content.

### Getting designs on the Canvas

There are a few ways to start creating designs. Pick whichever feels most natural.

<Steps>
  <Step title="Ask Agent in chat">
    Type what you want to see in the chat input and Agent places it as an interactive frame on the Canvas.

    <AgentInput defaultPrompt="Show me a mockup of my landing page on the canvas" showTypewriter={true} />
  </Step>

  <Step title="Pick an output type">
    You can also choose what kind of output you want — web, mobile, slides, design, and more. Use the carousel to pick before sending your prompt.

    <AgentCarousel />
  </Step>

  <Step title="Bring an existing page onto the Canvas">
    Already have a live app? Ask Agent to pull a page onto the Canvas for a redesign — for example, "Put my dashboard on the canvas." Agent makes a copy so your live app stays untouched.
  </Step>
</Steps>

## Making changes

Once you have a design on the Canvas, there are several ways to iterate on it.

### Ask Agent for updates

Select a frame on the Canvas and type your changes in the input that appears below it. When you press enter, Agent picks up the request, runs the updates, and refreshes the mockup right on the Canvas.

<Frame>
  <video autoPlay muted loop playsInline style={{ width: '100%', borderRadius: '8px' }}>
    <source src="https://mintcdn.com/replit/H-TDTs94BJ7lxH24/images/replitai/canvas-update.mp4?fit=max&auto=format&n=H-TDTs94BJ7lxH24&q=85&s=39c0b6f3185e51d8119e6caa3f2fd5d2" type="video/mp4" data-path="images/replitai/canvas-update.mp4" />
  </video>
</Frame>

### Draw and annotate

Use the drawing tools in the bottom toolbar to sketch directly on the Canvas. Draw arrows pointing to what you want changed, circle problem areas, or add text notes with your feedback. Then ask Agent to make the changes based on your annotations.

<Frame>
  <video autoPlay muted loop playsInline style={{ width: '100%', borderRadius: '8px' }}>
    <source src="https://mintcdn.com/replit/H-TDTs94BJ7lxH24/images/replitai/canvas-draw.mp4?fit=max&auto=format&n=H-TDTs94BJ7lxH24&q=85&s=042d1489c439b42d568fb40d88418bc0" type="video/mp4" data-path="images/replitai/canvas-draw.mp4" />
  </video>
</Frame>

### Preview on different devices

See how your designs look on different screen sizes. Ask Agent to show you a mobile, tablet, or desktop version:

* **Mobile** — 390 × 844
* **Tablet** — 768 × 1024
* **Desktop** — 1280 × 720

For example, "Show me the mobile version of this page" and Agent renders it at that size.

<Frame>
  <video autoPlay muted loop playsInline style={{ width: '100%', borderRadius: '8px' }}>
    <source src="https://mintcdn.com/replit/H-TDTs94BJ7lxH24/images/replitai/canvas-preview.mp4?fit=max&auto=format&n=H-TDTs94BJ7lxH24&q=85&s=013e4c6d0b2e991ef68fca9212c01bbb" type="video/mp4" data-path="images/replitai/canvas-preview.mp4" />
  </video>
</Frame>

### Apply changes to your app

When you're happy with a design, apply the changes back to your main version. Agent shows you a summary of what was done and gives you the option to apply or dismiss.

<Frame>
  <video autoPlay muted loop playsInline style={{ width: '100%', borderRadius: '8px' }}>
    <source src="https://mintcdn.com/replit/H-TDTs94BJ7lxH24/images/replitai/canvas-apply.mp4?fit=max&auto=format&n=H-TDTs94BJ7lxH24&q=85&s=6ec69132d43f5b8fa6e4fcf2d7dac003" type="video/mp4" data-path="images/replitai/canvas-apply.mp4" />
  </video>
</Frame>

## Comparing design directions

When you're not sure which direction to go, ask Agent to generate multiple versions so you can compare them side by side.

<Frame>
  <video autoPlay muted loop playsInline style={{ width: '100%', borderRadius: '8px' }}>
    <source src="https://mintcdn.com/replit/H-TDTs94BJ7lxH24/images/replitai/canvas-compare.mp4?fit=max&auto=format&n=H-TDTs94BJ7lxH24&q=85&s=b2d8eb92ea1330fc729fe1a118bea0b9" type="video/mp4" data-path="images/replitai/canvas-compare.mp4" />
  </video>
</Frame>

* **Multiple versions of one page**: "Show me five versions of this landing page." Agent creates each one and lays them out next to each other.
* **Multi-page flows**: "Design a complete onboarding flow: welcome, profile setup, preferences, and confirmation." Agent builds each screen and arranges them in order.
* **Mix and match**: "Show me the landing page and pricing page in both a minimal and a bold style." Agent creates every combination so you can see the full picture.

## Mapping out user flows

Lay out complete user journeys on the Canvas — sign-up, onboarding, dashboard, settings — and arrange them to see how everything connects.

* Place each screen as a separate frame
* Ask Agent to generate the full flow: "Draw out the complete onboarding flow for my app"
* Use arrows and shapes to show how users move between screens
* Ask Agent to turn rough sketches into polished designs

## Turning a design into a real app

When you're happy with a design and want to make it real, there are two paths:

### Make it a full app

If your design needs real functionality — like saving data, user accounts, or connecting to other services — ask Agent to turn it into a full app. Say something like "Make this a real app" or "Add a backend to this." Agent builds everything it needs to work as a real, publishable app.

<Note>
  Turning a design into a full app requires a paid plan.
</Note>

### Convert it to a specific type

You can also convert a design frame into a specific artifact type:

<Steps>
  <Step title="Select a frame">
    Click on the frame you want to convert.
  </Step>

  <Step title="Ask Agent to convert">
    Tell Agent what you want — for example, "Convert this into a web app" or "Turn this into slides."
  </Step>

  <Step title="Pick a type">
    Choose from web app, mobile app, slides, data visualization, and more.
  </Step>
</Steps>

## Frequently asked questions

<Accordion title="Are design frames the same as my running app?">
  No. Design frames are visual prototypes — they look and feel like the real thing, but they don't have a working backend or database behind them. Your app previews on the Canvas, on the other hand, are your actual running app.
</Accordion>

<Accordion title="Can I redesign a page without breaking my live app?">
  Yes. Ask Agent to bring a page onto the Canvas — for example, "Put my dashboard on the canvas." Agent makes a copy you can experiment with. Your live app isn't affected until you choose to apply the changes.
</Accordion>

<Accordion title="How do I turn a design into a real app?">
  Ask Agent to make it a full app ("Make this real") or convert it to a specific type ("Convert this to a web app"). Agent builds everything it needs to become a working, publishable app.
</Accordion>

<Accordion title="Can I convert to types other than web apps?">
  Yes. You can turn Canvas frames into web apps, mobile apps, slides, data visualizations, and more.
</Accordion>

<Accordion title="Can I import designs from Figma or other tools?">
  Yes. There are a few ways to bring Figma designs into Replit:

  * **Import from Figma**: Go to [replit.com/import](https://replit.com/import), connect your Figma account, and paste a frame URL to convert a design into a working React app. See the [Import from Figma quickstart](/getting-started/quickstarts/import-from-figma) for details.
  * **Figma MCP in Agent chat**: Paste a Figma link directly into Agent chat and ask it to generate code, extract design data, or build out a component from the design. See the [Figma MCP Integration](/replitai/mcp/figma) guide.
  * **Screenshot reference**: Drop a screenshot onto the Canvas and ask Agent to recreate the design from it.
</Accordion>

<Accordion title="What else can I put on the Canvas?">
  Besides design mockups and app previews, you can add shapes, arrows, text labels, sticky notes, images, and videos — useful for sketching ideas, annotating designs, or organizing your thinking.
</Accordion>

## Availability

The Canvas is available on all plans, including frame creation, inline editing, variant generation, and conversion to artifacts. Turning designs into full apps requires a paid plan.
